mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-28 19:02:49 +03:00
Compare commits
214 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
48c777be11 | ||
|
|
84a50beefc | ||
|
|
ab7908e012 | ||
|
|
388e0fe845 | ||
|
|
60b632418f | ||
|
|
89c81bd88b | ||
|
|
99b9b99343 | ||
|
|
0b5dbd6f5c | ||
|
|
726673f926 | ||
|
|
6a522b381c | ||
|
|
1882d263b9 | ||
|
|
b0683f77c2 | ||
|
|
7aceabed07 | ||
|
|
11c51500b3 | ||
|
|
fa886231d3 | ||
|
|
5085dcf96f | ||
|
|
34bcb2b609 | ||
|
|
c608742b84 | ||
|
|
d33c0ed1b5 | ||
|
|
d34618003d | ||
|
|
a24854a3cc | ||
|
|
f1e30dfba2 | ||
|
|
7b75476c4a | ||
|
|
b7bd41942d | ||
|
|
78db90e4bf | ||
|
|
592ca9b5c4 | ||
|
|
9981394557 | ||
|
|
b100325fe0 | ||
|
|
0ddfb48a98 | ||
|
|
d6610b7f8f | ||
|
|
ea540569ed | ||
|
|
e91d19e132 | ||
|
|
bd281e5753 | ||
|
|
7c59f05681 | ||
|
|
6dcde9fcbe | ||
|
|
cc048e55bf | ||
|
|
dd556b44e8 | ||
|
|
c62145af31 | ||
|
|
9148dc9e03 | ||
|
|
606824d282 | ||
|
|
231ca8a935 | ||
|
|
c96221c705 | ||
|
|
19f46eb817 | ||
|
|
185d53da6a | ||
|
|
07c1071c36 | ||
|
|
a9d0453811 | ||
|
|
54ef217de4 | ||
|
|
0ebfa89783 | ||
|
|
2a8b155a16 | ||
|
|
dd814d1591 | ||
|
|
1ba9ff8153 | ||
|
|
1121b81f12 | ||
|
|
f7fbe3946d | ||
|
|
921bfbbe3c | ||
|
|
bca3cb8303 | ||
|
|
fb03687802 | ||
|
|
c0e6a85ffd | ||
|
|
7f723a6bd5 | ||
|
|
02bc2e3ddb | ||
|
|
3c8e448ffb | ||
|
|
7885153933 | ||
|
|
f5161404cb | ||
|
|
a668ac7235 | ||
|
|
2610a286ca | ||
|
|
6daa065b1e | ||
|
|
1b873d3bad | ||
|
|
a0cfae214d | ||
|
|
db0af86085 | ||
|
|
be2f7cb3e5 | ||
|
|
082cb86a23 | ||
|
|
0420144104 | ||
|
|
22656c8699 | ||
|
|
c1c78164d2 | ||
|
|
08f1f05d58 | ||
|
|
c40b67fe77 | ||
|
|
81ebcc9a72 | ||
|
|
9ccc7feb58 | ||
|
|
7706adc444 | ||
|
|
7c76f7443e | ||
|
|
314ef361b6 | ||
|
|
ef401a1a2c | ||
|
|
a0877e484d | ||
|
|
067e0220bd | ||
|
|
da6481f96b | ||
|
|
7dea0441ac | ||
|
|
34c41d5f3d | ||
|
|
77d8dce81c | ||
|
|
d3058cbe07 | ||
|
|
587bab3eb1 | ||
|
|
a36a38bd8d | ||
|
|
629a6936fa | ||
|
|
4e7e50754d | ||
|
|
0288bc681b | ||
|
|
d46e3f07c3 | ||
|
|
d512ab5ddf | ||
|
|
2a052b2db1 | ||
|
|
3ada6d1bff | ||
|
|
86030a0fab | ||
|
|
954c40067e | ||
|
|
6a36606bd5 | ||
|
|
20a72a0f45 | ||
|
|
bcc374eb31 | ||
|
|
f0e1f18c79 | ||
|
|
61b7203062 | ||
|
|
a7e95d00cf | ||
|
|
83c358deb1 | ||
|
|
7dd214f3db | ||
|
|
6698d33f04 | ||
|
|
6dcd5b77aa | ||
|
|
80f2c797c9 | ||
|
|
910471a26f | ||
|
|
ccab588948 | ||
|
|
50683e6600 | ||
|
|
75daf98112 | ||
|
|
9a681a27ad | ||
|
|
25c63c8b10 | ||
|
|
a069df41b8 | ||
|
|
b1183c2c9d | ||
|
|
b777b15ee8 | ||
|
|
35061dfc53 | ||
|
|
a65bca6e49 | ||
|
|
72203f2721 | ||
|
|
03ff03ed52 | ||
|
|
488d50b97e | ||
|
|
88cbd1bd83 | ||
|
|
27fe556bab | ||
|
|
3191b7a991 | ||
|
|
f8d045c275 | ||
|
|
0038fe5ff1 | ||
|
|
3ae810a18e | ||
|
|
afe72c8029 | ||
|
|
2341bba973 | ||
|
|
c0da968af2 | ||
|
|
03fb04f4c5 | ||
|
|
d71c4a0ea7 | ||
|
|
df206d9792 | ||
|
|
49ad44dcaf | ||
|
|
7f785b8fa5 | ||
|
|
b4e674aeb0 | ||
|
|
8ed091703f | ||
|
|
464fd6d4d3 | ||
|
|
a96dfdda67 | ||
|
|
5b140d26c3 | ||
|
|
125fb81fa3 | ||
|
|
ee14372e20 | ||
|
|
5c27e0f9ef | ||
|
|
7607cec7a2 | ||
|
|
5f9c93369e | ||
|
|
9e4132fd3f | ||
|
|
0ae31e0acc | ||
|
|
24721cf2fa | ||
|
|
2ab41a359e | ||
|
|
c87167cac4 | ||
|
|
46311dfaba | ||
|
|
03720bbb81 | ||
|
|
3319fd6a21 | ||
|
|
0f75387f41 | ||
|
|
9fd5d8241e | ||
|
|
0bfee823dd | ||
|
|
668b235b07 | ||
|
|
ea6d0f573d | ||
|
|
d1b8afd3b8 | ||
|
|
0f8b9ca55b | ||
|
|
b5c84a91fb | ||
|
|
cc902db4ab | ||
|
|
faae82eae1 | ||
|
|
49ac0cadfb | ||
|
|
bd5f39e1c6 | ||
|
|
325d048340 | ||
|
|
f1805c8536 | ||
|
|
305545623a | ||
|
|
aac99f6ee2 | ||
|
|
4feea2e721 | ||
|
|
0e73b3b8e1 | ||
|
|
4b0bcf4464 | ||
|
|
57ef0ad41d | ||
|
|
a92d6b75bf | ||
|
|
763da979a8 | ||
|
|
8c58f7a04e | ||
|
|
e1868bdb78 | ||
|
|
ed72ddc4d3 | ||
|
|
a7fa34c2fc | ||
|
|
51c734e438 | ||
|
|
ad676af3f0 | ||
|
|
1251353694 | ||
|
|
4d97023938 | ||
|
|
adf77053c5 | ||
|
|
9c57888524 | ||
|
|
dd33dc1f9b | ||
|
|
90ed6163f5 | ||
|
|
8f162cd57c | ||
|
|
e7e4bf39fe | ||
|
|
d9341e033b | ||
|
|
bf7d4ebea5 | ||
|
|
8d4a4dc526 | ||
|
|
2a3a0c758a | ||
|
|
94eb7b155e | ||
|
|
50f12869bf | ||
|
|
c81c79ad52 | ||
|
|
f2f6f2f5a8 | ||
|
|
2e2afa616d | ||
|
|
d82a7040f1 | ||
|
|
8fc97a7f91 | ||
|
|
5789c1ae7d | ||
|
|
520a89f5f6 | ||
|
|
15379384dd | ||
|
|
622c4f9f6f | ||
|
|
b7316353f4 | ||
|
|
902a2723ae | ||
|
|
57f3c67e28 | ||
|
|
6a2bc1ef2b | ||
|
|
41f9f96819 | ||
|
|
3f82b05f4f | ||
|
|
1fca80e27d |
49
.agents/workflows/capture-release-evidences.md
Normal file
49
.agents/workflows/capture-release-evidences.md
Normal file
@@ -0,0 +1,49 @@
|
||||
---
|
||||
description: Automatically run the browser_subagent to visually validate all new UI features from the current release and capture evidence WebP recordings of the changes.
|
||||
---
|
||||
|
||||
# Capture Release Evidences Workflow
|
||||
|
||||
Use this workflow to automatically drive the `browser_subagent` to explore the newly deployed or locally running application and record evidence of the UI changes introduced in the latest release.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- OmniRoute must be actively running and accessible (e.g. locally at `http://localhost:20128` or on the Local VPS at `http://192.168.0.15:20128`).
|
||||
- The user must provide the target URL to be tested, or default to `http://192.168.0.15:20128`.
|
||||
|
||||
## Workflow Steps
|
||||
|
||||
### 1. Identify Target Features
|
||||
|
||||
Review the `CHANGELOG.md` for the latest version to map out the new UI elements. For example:
|
||||
|
||||
- **CLI Tools Settings**
|
||||
- **New Provider/Model Listings (e.g., Gemini 3.1, Qoder PAT)**
|
||||
- **New Feature Modals**
|
||||
|
||||
### 2. Run the Browser Subagent
|
||||
|
||||
For each identified feature, invoke the `browser_subagent` using the `default_api:browser_subagent` tool.
|
||||
**Important Task Guidelines for the Subagent:**
|
||||
|
||||
- `TaskName`: Give it a clear name like "Validate CLIProxyAPI Tool Tab".
|
||||
- `TaskSummary`: "Navigate to the CLI Tools tab and verify the new Integration settings."
|
||||
- `Task`: Provide unambiguous instructions for the subagent, such as: "Navigate to http://192.168.0.15:20128/dashboard. Click on the 'Settings' or 'CLI Tools' nav link. Scroll down to find the CLIProxyAPI integration card. Hover over it to trigger UI state. Verify the components render correctly and exit."
|
||||
- `RecordingName`: Ensure it describes the feature (e.g. `v3_4_5_cli_proxy_api`). This is required and strictly automatically saved as a WebP artifacts video by the system.
|
||||
|
||||
_(Note: The `browser_subagent` automatically creates a WebP recording named by the `RecordingName` parameter. No additional tools for screenshots are needed.)_
|
||||
|
||||
### 3. Generate Report Artifact
|
||||
|
||||
After the `browser_subagent` finishes its sessions, generate a final Markdown artifact (using `write_to_file` and `IsArtifact=true`) to present the recordings inline to the user using the `` syntax.
|
||||
|
||||
### Example Invocation
|
||||
|
||||
\```json
|
||||
{
|
||||
"TaskName": "Validating Qoder PAT Configuration UI",
|
||||
"TaskSummary": "Validates the Qoder provider configuration modal",
|
||||
"Task": "Go to http://192.168.0.15:20128/dashboard. Click on the 'Providers' tab. Find 'Qoder' in the list. Click 'Add Token' or 'Configure'. Type 'test_token' and submit. Return when done.",
|
||||
"RecordingName": "qoder_pat_ui_validation"
|
||||
}
|
||||
\```
|
||||
@@ -17,7 +17,7 @@ Deploy OmniRoute to the Akamai VPS using `npm pack + scp` + PM2.
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && npm pack --ignore-scripts
|
||||
cd /home/diegosouzapw/dev/proxys/9router && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
|
||||
```
|
||||
|
||||
### 2. Copy to Akamai VPS and install
|
||||
|
||||
@@ -22,7 +22,7 @@ Deploy OmniRoute to the production VPSs using `npm pack + scp` + PM2.
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && npm pack --ignore-scripts
|
||||
cd /home/diegosouzapw/dev/proxys/9router && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
|
||||
```
|
||||
|
||||
### 2. Copy to both VPS and install
|
||||
|
||||
@@ -17,7 +17,7 @@ Deploy OmniRoute to the Local VPS using `npm pack + scp` + PM2.
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && npm pack --ignore-scripts
|
||||
cd /home/diegosouzapw/dev/proxys/9router && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
|
||||
```
|
||||
|
||||
### 2. Copy to Local VPS and install
|
||||
|
||||
@@ -27,6 +27,23 @@ Phase 2 (post-merge): tag → publish → GitHub release → Docker → deploy
|
||||
|
||||
---
|
||||
|
||||
## Phase 0: Security Verification (MANDATORY)
|
||||
|
||||
Before creating the release, you must ensure the codebase and supply chain are secure and free of known vulnerabilities.
|
||||
|
||||
1. **Run Local Dependencies Audit:**
|
||||
|
||||
```bash
|
||||
npm audit
|
||||
```
|
||||
|
||||
_Fix any `high` or `critical` vulnerabilities identified._
|
||||
|
||||
2. **Check GitHub CodeQL & Dependabot Alerts:**
|
||||
Navigate to the repository's **Security** tab on GitHub, or use the project's `vulnerability-scanner` skill to analyze active alerts. Ensure all static analysis findings (e.g., prototype pollution, insecure randomness, ReDoS, shell injections) are addressed and logically committed on a target branch.
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Pre-Merge
|
||||
|
||||
### 1. Create release branch
|
||||
@@ -221,15 +238,15 @@ gh workflow run docker-publish.yml --repo diegosouzapw/OmniRoute --ref v2.x.y
|
||||
|
||||
```bash
|
||||
# Build and pack locally
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && npm pack --ignore-scripts
|
||||
cd /home/diegosouzapw/dev/proxys/9router && rm -f omniroute-*.tgz && rm -rf .next/cache app/.next/cache && npm run build:cli && rm -rf app/logs app/coverage app/.git app/.app-build-backup* && npm pack --ignore-scripts
|
||||
|
||||
# Deploy to LOCAL VPS (192.168.0.15)
|
||||
scp omniroute-*.tgz root@192.168.0.15:/tmp/
|
||||
ssh root@192.168.0.15 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts && pm2 restart omniroute && pm2 save"
|
||||
ssh root@192.168.0.15 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && pm2 delete omniroute 2>/dev/null; pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo '✅ Local done'"
|
||||
|
||||
# Deploy to AKAMAI VPS (69.164.221.35)
|
||||
scp omniroute-*.tgz root@69.164.221.35:/tmp/
|
||||
ssh root@69.164.221.35 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts && pm2 restart omniroute && pm2 save"
|
||||
ssh root@69.164.221.35 "npm install -g /tmp/omniroute-*.tgz --ignore-scripts && cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 && pm2 delete omniroute 2>/dev/null; pm2 start /root/.omniroute/ecosystem.config.cjs --update-env && pm2 save && echo '✅ Akamai done'"
|
||||
|
||||
# Verify both
|
||||
curl -s -o /dev/null -w "LOCAL: HTTP %{http_code}\n" http://192.168.0.15:20128/
|
||||
|
||||
@@ -68,49 +68,78 @@ For each issue, determine its type:
|
||||
|
||||
Focus ONLY on **Bugs** for resolution. Feature requests and questions should be skipped with a note in the final report.
|
||||
|
||||
### 5. Analyze Each Bug — For each bug issue:
|
||||
### 5. Deep-Read Each Bug Issue (One-by-One Analysis)
|
||||
|
||||
#### 5a. Check Information Sufficiency
|
||||
**IMPORTANT**: Read each bug issue thoroughly, one at a time, before moving to the next. This is NOT a batch process — each issue needs focused attention.
|
||||
|
||||
Verify the issue contains enough information to reproduce and fix:
|
||||
#### 5a. Understand the Problem
|
||||
|
||||
For each bug issue, perform the full analysis:
|
||||
|
||||
1. **Read the entire body** — including Description, Steps to Reproduce, Expected/Actual Behavior, Error Logs, and Screenshots
|
||||
2. **Read ALL comments** — including bot triage comments (Kilo, etc.) and owner/community responses. Pay attention to:
|
||||
- Whether someone already responded with a fix
|
||||
- Whether a community member confirmed the issue is resolved
|
||||
- Whether the issue was marked as duplicate by a bot
|
||||
3. **Identify the claimed error** — extract the exact error message, status code, and provider/model involved
|
||||
|
||||
#### 5b. Check Information Sufficiency
|
||||
|
||||
Verify the issue contains enough to act on:
|
||||
|
||||
- [ ] Clear description of the problem
|
||||
- [ ] Steps to reproduce
|
||||
- [ ] Error messages or logs
|
||||
- [ ] Steps to reproduce OR error logs
|
||||
- [ ] Provider/model/version information
|
||||
- [ ] Expected vs actual behavior
|
||||
|
||||
#### 5b. If Information Is INSUFFICIENT
|
||||
#### 5c. Determine Issue Disposition
|
||||
|
||||
Call the `/issue-triage` workflow (located at `~/.gemini/antigravity/global_workflows/issue-triage.md`):
|
||||
// turbo
|
||||
For each bug, classify into one of 5 actions:
|
||||
|
||||
- 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
|
||||
| Disposition | When to Apply | Action |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------- | --------------------------------------------------- |
|
||||
| **✅ CLOSE — Already Fixed** | Owner responded with fix + no user follow-up, OR community confirmed fix | Close with comment citing which version fixed it |
|
||||
| **✅ CLOSE — Duplicate** | Bot flagged >85% similarity + user provides no new info | Close referencing the original issue |
|
||||
| **📝 RESPOND — Needs Info** | Issue is real but missing critical reproduction details | Comment asking for specifics per `/issue-triage` |
|
||||
| **📝 RESPOND — User Config** | Error is caused by unsupported env (Node version, wrong model path, missing API enablement) | Comment explaining the user-side fix |
|
||||
| **🔧 FIX — Code Change** | Root cause is confirmed in the codebase | Research, implement, test, commit on release branch |
|
||||
|
||||
#### 5c. If Information Is SUFFICIENT
|
||||
#### 5d. For "FIX — Code Change" Issues
|
||||
|
||||
Proceed with resolution **on the release branch**:
|
||||
Before coding, perform deep source analysis:
|
||||
|
||||
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>)`
|
||||
1. **Search the codebase** — `grep_search` for error strings, relevant function names, affected files
|
||||
2. **Search the web** — for upstream API changes, SDK updates, or breaking changes that explain the bug
|
||||
3. **Read the full source file** — don't rely on grep snippets; understand the surrounding logic
|
||||
4. **Verify the root cause** — confirm the bug is reproducible based on the code, not just a user misconfiguration
|
||||
5. **Implement the fix** — follow existing code patterns and conventions
|
||||
6. **Run tests** — `node --import tsx/esm --test tests/unit/*.test.mjs` (must pass 100%)
|
||||
7. **Commit** — `fix: <description> (#<issue_number>)`
|
||||
|
||||
> **⚠️ Do NOT create a separate branch.** All commits go directly on the release branch.
|
||||
#### 5e. For "RESPOND" Issues
|
||||
|
||||
Post a substantive comment that:
|
||||
|
||||
- Acknowledges the specific error they reported
|
||||
- Explains the likely root cause
|
||||
- Provides concrete steps to resolve (version upgrade, env var fix, model path correction)
|
||||
- Asks for follow-up info if needed
|
||||
|
||||
**Do NOT post generic template responses.** Every comment should reference the user's specific error messages and environment.
|
||||
|
||||
### 6. Generate Report & Wait for Validation
|
||||
|
||||
Present a summary report to the user via `notify_user` with `BlockedOnUser: true`:
|
||||
|
||||
| Issue | Title | Status | Action |
|
||||
| ----- | ----- | ------------- | ----------------------------- |
|
||||
| #N | Title | ✅ Ready | Files changed (not committed) |
|
||||
| #N | Title | ❓ Needs Info | Triage comment posted |
|
||||
| #N | Title | ⏭️ Skipped | Feature request / not a bug |
|
||||
| Issue | Title | Status | Action |
|
||||
| ----- | ----- | ------------- | --------------------------- |
|
||||
| #N | Title | ✅ Closed | Already fixed / duplicate |
|
||||
| #N | Title | 🔧 Fixed | Code fix applied |
|
||||
| #N | Title | 📝 Responded | Guidance comment posted |
|
||||
| #N | Title | ❓ Needs Info | Triage comment posted |
|
||||
| #N | Title | ⏭️ Skipped | Feature request / not a bug |
|
||||
|
||||
> **⚠️ IMPORTANT**: Do NOT commit, close issues, or generate releases at this step.
|
||||
> **⚠️ IMPORTANT**: Do NOT merge or generate releases at this step.
|
||||
> Wait for the user to review the changes and respond with **OK** before proceeding.
|
||||
|
||||
- If the user says **OK** or approves → Proceed to step 7
|
||||
|
||||
17
.env.example
17
.env.example
@@ -189,10 +189,21 @@ GEMINI_CLI_USER_AGENT=google-api-nodejs-client/9.15.1
|
||||
# Provider keys above (openai, mistral, together, fireworks, nvidia) also work for embeddings
|
||||
|
||||
# Timeout settings
|
||||
# FETCH_TIMEOUT_MS=120000
|
||||
# STREAM_IDLE_TIMEOUT_MS=60000
|
||||
# REQUEST_TIMEOUT_MS=600000
|
||||
# STREAM_IDLE_TIMEOUT_MS=600000
|
||||
# Advanced timeout overrides (optional)
|
||||
# FETCH_TIMEOUT_MS=600000
|
||||
# FETCH_HEADERS_TIMEOUT_MS=600000
|
||||
# FETCH_BODY_TIMEOUT_MS=600000
|
||||
# FETCH_CONNECT_TIMEOUT_MS=30000
|
||||
# FETCH_KEEPALIVE_TIMEOUT_MS=4000
|
||||
# TLS_CLIENT_TIMEOUT_MS=600000
|
||||
# API bridge timeout for /v1 proxy requests (default: 30000)
|
||||
# API_BRIDGE_PROXY_TIMEOUT_MS=120000
|
||||
# API_BRIDGE_PROXY_TIMEOUT_MS=600000
|
||||
# API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS=600000
|
||||
# API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS=60000
|
||||
# API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS=5000
|
||||
# API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS=0
|
||||
|
||||
# CORS configuration (default: * allows all origins)
|
||||
# CORS_ORIGINS=*
|
||||
|
||||
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
* @diegosouzapw
|
||||
|
||||
26
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
26
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -119,6 +119,20 @@ body:
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: test-impact
|
||||
attributes:
|
||||
label: Test Impact
|
||||
description: "What automated test coverage should exist for this bug?"
|
||||
options:
|
||||
- Needs a new unit test
|
||||
- Needs a new integration test
|
||||
- Needs a new e2e test
|
||||
- Existing automated test already fails
|
||||
- Unsure
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: logs
|
||||
attributes:
|
||||
@@ -143,3 +157,15 @@ body:
|
||||
description: "Any other context about the problem (e.g. proxy config, number of accounts, network setup)."
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: validation-plan
|
||||
attributes:
|
||||
label: Validation Plan
|
||||
description: "Which commands or tests should prove this bug is fixed?"
|
||||
placeholder: |
|
||||
Example:
|
||||
- node --import tsx/esm --test tests/unit/my-file.test.mjs
|
||||
- npm run test:coverage
|
||||
validations:
|
||||
required: false
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -1,4 +1,4 @@
|
||||
blank_issues_enabled: true
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Question / Help
|
||||
url: https://github.com/diegosouzapw/OmniRoute/discussions
|
||||
|
||||
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
26
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -33,6 +33,19 @@ body:
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: acceptance
|
||||
attributes:
|
||||
label: Acceptance Criteria
|
||||
description: "Describe the concrete behaviors or outcomes that should be validated before this is considered done."
|
||||
placeholder: |
|
||||
Example:
|
||||
- API route returns 200 with valid payload
|
||||
- Unit coverage added for the new branch
|
||||
- Existing integrations remain green
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: dropdown
|
||||
id: area
|
||||
attributes:
|
||||
@@ -68,3 +81,16 @@ body:
|
||||
description: "Any other context, mockups, or references."
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
id: test-plan
|
||||
attributes:
|
||||
label: Expected Test Plan
|
||||
description: "Which automated tests or coverage changes should accompany this work?"
|
||||
placeholder: |
|
||||
Example:
|
||||
- Add unit tests for open-sse/services/combo.ts
|
||||
- Extend integration coverage for /api/v1/models
|
||||
- Keep npm run test:coverage at 60%+
|
||||
validations:
|
||||
required: false
|
||||
|
||||
73
.github/ISSUE_TEMPLATE/test_coverage_task.yml
vendored
Normal file
73
.github/ISSUE_TEMPLATE/test_coverage_task.yml
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
name: Test Coverage Task
|
||||
description: Create a focused coverage-improvement issue tied to concrete files and targets
|
||||
title: "[Coverage] "
|
||||
labels: ["test", "coverage"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Use this template for scoped coverage work. Keep it tied to specific files, measurable targets, and the gate that must stay green.
|
||||
|
||||
- type: input
|
||||
id: baseline
|
||||
attributes:
|
||||
label: Current Coverage Baseline
|
||||
description: "Paste the current overall or file-level coverage number that justifies this task."
|
||||
placeholder: "e.g. Lines 79.00%, Branches 72.85%, open-sse/handlers/chatCore.ts = 67.22%"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: scope
|
||||
attributes:
|
||||
label: Target Files Or Modules
|
||||
description: "List the concrete source files or directories that this task will cover."
|
||||
placeholder: |
|
||||
Example:
|
||||
- open-sse/handlers/chatCore.ts
|
||||
- open-sse/services/combo.ts
|
||||
- tests/integration/chat-pipeline.test.mjs
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: scenarios
|
||||
attributes:
|
||||
label: Missing Scenarios
|
||||
description: "Describe the specific behaviors, branches, or failure paths that are currently uncovered."
|
||||
placeholder: |
|
||||
Example:
|
||||
- Upstream timeout path
|
||||
- Empty tool_calls normalization
|
||||
- Fallback route after first provider failure
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: input
|
||||
id: target
|
||||
attributes:
|
||||
label: Coverage Target
|
||||
description: "Set the expected target for this task."
|
||||
placeholder: "e.g. Raise open-sse/handlers to 80%+ lines and keep global gate >= 60%"
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: validation
|
||||
attributes:
|
||||
label: Validation Commands
|
||||
description: "List the commands that must pass before this issue can be closed."
|
||||
placeholder: |
|
||||
Example:
|
||||
- node --import tsx/esm --test tests/unit/my-suite.test.mjs
|
||||
- npm run test:coverage
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
id: notes
|
||||
attributes:
|
||||
label: Notes
|
||||
description: "Optional context, blockers, or dependencies."
|
||||
validations:
|
||||
required: false
|
||||
15
.github/copilot-instructions.md
vendored
Normal file
15
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
# OmniRoute PR and Coverage Instructions
|
||||
|
||||
- Treat `npm run test:coverage` as a required gate for PR work.
|
||||
- The repository minimum is `60%` for statements, lines, functions, and branches.
|
||||
- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must include automated tests in the same PR.
|
||||
- When reviewing or updating a PR, if the report shows missing tests or coverage below `60%`, do not stop after reporting the problem. Add or update tests in the PR first, rerun the coverage gate, and only then ask for confirmation.
|
||||
- Prefer the smallest test layer that proves the behavior:
|
||||
- unit tests first
|
||||
- integration tests when multiple modules or DB state are involved
|
||||
- e2e only when the behavior is truly UI or workflow-dependent
|
||||
- For bug issues, try to encode the reproduction as an automated test before or alongside the fix.
|
||||
- In the final PR report, include:
|
||||
- the commands you ran
|
||||
- the changed test files
|
||||
- the final coverage result
|
||||
30
.github/pull_request_template.md
vendored
Normal file
30
.github/pull_request_template.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
## Summary
|
||||
|
||||
- Describe the user-facing or operational change.
|
||||
|
||||
## Related Issues
|
||||
|
||||
- Closes #
|
||||
- Related to #
|
||||
|
||||
## Validation
|
||||
|
||||
- [ ] `npm run lint`
|
||||
- [ ] `npm run test:unit`
|
||||
- [ ] `npm run test:coverage`
|
||||
- [ ] Coverage is still `>= 60%` for statements, lines, functions, and branches
|
||||
- [ ] SonarQube PR analysis is green or any remaining issues are explicitly documented below
|
||||
|
||||
## Tests Added Or Updated
|
||||
|
||||
- List every changed or added automated test file.
|
||||
- If no production code changed, state that here.
|
||||
|
||||
## Coverage Notes
|
||||
|
||||
- If this PR changes `src/`, `open-sse/`, `electron/`, or `bin/`, explain which tests cover the change.
|
||||
- If coverage moved down in any touched file, explain why and what follow-up task will recover it.
|
||||
|
||||
## Reviewer Notes
|
||||
|
||||
- Call out any risky areas, migrations, feature flags, or manual validation that reviewers should know about.
|
||||
345
.github/workflows/ci.yml
vendored
345
.github/workflows/ci.yml
vendored
@@ -5,6 +5,7 @@ on:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
types: [opened, synchronize, reopened, ready_for_review]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
@@ -14,13 +15,12 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
|
||||
lint:
|
||||
name: Lint
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
@@ -39,12 +39,12 @@ jobs:
|
||||
outputs:
|
||||
langs: ${{ steps.langs.outputs.langs }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- id: langs
|
||||
run: |
|
||||
LANG_DIR="src/i18n/messages"
|
||||
LANGS=$(ls "$LANG_DIR"/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$' | jq -R . | jq -s . | jq -c .)
|
||||
echo "langs=${LANGS}" >> $GITHUB_OUTPUT
|
||||
echo "langs=${LANGS}" >> "$GITHUB_OUTPUT"
|
||||
|
||||
i18n:
|
||||
name: i18n Validation
|
||||
@@ -56,10 +56,10 @@ jobs:
|
||||
lang: ${{ fromJson(needs.i18n-matrix.outputs.langs) }}
|
||||
needs: i18n-matrix
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-python@v6.2.0
|
||||
with:
|
||||
python-version: '3.12'
|
||||
python-version: "3.12"
|
||||
|
||||
- name: Validate ${{ matrix.lang }}
|
||||
run: |
|
||||
@@ -72,21 +72,63 @@ jobs:
|
||||
name: i18n-${{ matrix.lang }}
|
||||
path: result.txt
|
||||
|
||||
security:
|
||||
name: Security Audit
|
||||
pr-test-policy:
|
||||
name: PR Test Policy
|
||||
if: ${{ github.event_name == 'pull_request' }}
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
- name: Fetch base branch
|
||||
run: git fetch --no-tags origin "${GITHUB_BASE_REF}" --depth=1
|
||||
- name: Validate source changes include tests
|
||||
run: node scripts/check-pr-test-policy.mjs --summary-file .artifacts/pr-test-policy.md
|
||||
- name: Publish PR test policy summary
|
||||
if: always()
|
||||
run: |
|
||||
if [ -f .artifacts/pr-test-policy.md ]; then
|
||||
cat .artifacts/pr-test-policy.md >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
|
||||
advanced-security:
|
||||
name: Advanced Security Scans
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: TruffleHog Secret Scan
|
||||
uses: trufflesecurity/trufflehog@main
|
||||
with:
|
||||
path: ./
|
||||
base: ${{ github.event.repository.default_branch }}
|
||||
head: HEAD
|
||||
extra_args: --only-verified
|
||||
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
|
||||
- run: npm ci
|
||||
|
||||
- name: Dependency audit
|
||||
run: npm audit --audit-level=high --omit=dev
|
||||
run: npm audit --audit-level=high --omit=dev || true
|
||||
|
||||
- name: Check for known vulnerabilities
|
||||
run: npx is-my-node-vulnerable
|
||||
continue-on-error: true
|
||||
run: npx is-my-node-vulnerable || true
|
||||
|
||||
- name: Run Snyk Vulnerability checks
|
||||
uses: snyk/actions/node@master
|
||||
env:
|
||||
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
|
||||
with:
|
||||
args: --severity-threshold=high
|
||||
|
||||
build:
|
||||
name: Build
|
||||
@@ -95,8 +137,8 @@ jobs:
|
||||
matrix:
|
||||
node-version: [20, 22]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
@@ -106,6 +148,7 @@ jobs:
|
||||
test-unit:
|
||||
name: Unit Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
@@ -114,8 +157,8 @@ jobs:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
API_KEY_SECRET: ci-test-api-key-secret-long
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}
|
||||
cache: npm
|
||||
@@ -125,40 +168,180 @@ jobs:
|
||||
test-coverage:
|
||||
name: Coverage
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
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@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run test:coverage
|
||||
- name: Run coverage gate
|
||||
run: npm run test:coverage
|
||||
- name: Build coverage summary
|
||||
if: always()
|
||||
run: |
|
||||
mkdir -p coverage
|
||||
if [ -f coverage/coverage-summary.json ]; then
|
||||
node scripts/test-report-summary.mjs \
|
||||
--input coverage/coverage-summary.json \
|
||||
--output coverage/coverage-report.md \
|
||||
--threshold 60
|
||||
else
|
||||
printf '%s\n' \
|
||||
'# Coverage Report' \
|
||||
'' \
|
||||
'Coverage summary JSON was not generated. Inspect the Coverage job logs.' \
|
||||
> coverage/coverage-report.md
|
||||
fi
|
||||
cat coverage/coverage-report.md >> "$GITHUB_STEP_SUMMARY"
|
||||
- name: Upload coverage artifacts
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: |
|
||||
coverage/coverage-summary.json
|
||||
coverage/lcov.info
|
||||
coverage/coverage-report.md
|
||||
if-no-files-found: warn
|
||||
|
||||
sonarqube:
|
||||
name: SonarQube
|
||||
runs-on: ubuntu-latest
|
||||
needs: test-coverage
|
||||
if: ${{ always() && needs.test-coverage.result == 'success' }}
|
||||
env:
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: .
|
||||
- name: Explain SonarQube skip
|
||||
if: ${{ env.SONAR_TOKEN == '' || env.SONAR_HOST_URL == '' }}
|
||||
run: |
|
||||
echo "SonarQube scan skipped because SONAR_TOKEN or SONAR_HOST_URL is not configured." >> "$GITHUB_STEP_SUMMARY"
|
||||
- name: SonarQube Scan
|
||||
if: ${{ env.SONAR_TOKEN != '' && env.SONAR_HOST_URL != '' }}
|
||||
uses: SonarSource/sonarqube-scan-action@v7
|
||||
env:
|
||||
SONAR_TOKEN: ${{ env.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ env.SONAR_HOST_URL }}
|
||||
|
||||
coverage-pr-comment:
|
||||
name: PR Coverage Comment
|
||||
runs-on: ubuntu-latest
|
||||
if: ${{ always() && github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false }}
|
||||
needs:
|
||||
- pr-test-policy
|
||||
- test-coverage
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Download coverage artifact
|
||||
if: ${{ needs.test-coverage.result != 'cancelled' }}
|
||||
continue-on-error: true
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: coverage-report
|
||||
path: .
|
||||
- name: Prepare PR coverage comment
|
||||
env:
|
||||
COVERAGE_RESULT: ${{ needs.test-coverage.result }}
|
||||
POLICY_RESULT: ${{ needs.pr-test-policy.result }}
|
||||
run: |
|
||||
mkdir -p .artifacts
|
||||
{
|
||||
echo "<!-- omniroute-coverage-report -->"
|
||||
echo "## CI Coverage Report"
|
||||
echo ""
|
||||
echo "- Coverage job: \`${COVERAGE_RESULT}\`"
|
||||
echo "- PR test policy: \`${POLICY_RESULT}\`"
|
||||
echo ""
|
||||
if [ -f coverage/coverage-report.md ]; then
|
||||
cat coverage/coverage-report.md
|
||||
else
|
||||
echo "Coverage artifact was not available for this run."
|
||||
fi
|
||||
if [ "${POLICY_RESULT}" = "failure" ]; then
|
||||
echo ""
|
||||
echo "## PR Test Policy"
|
||||
echo ""
|
||||
echo "This PR changes production code in \`src/\`, \`open-sse/\`, \`electron/\`, or \`bin/\` without accompanying automated tests."
|
||||
fi
|
||||
} > .artifacts/pr-coverage-comment.md
|
||||
- uses: actions/github-script@v8
|
||||
with:
|
||||
script: |
|
||||
const fs = require("fs");
|
||||
const marker = "<!-- omniroute-coverage-report -->";
|
||||
const body = fs.readFileSync(".artifacts/pr-coverage-comment.md", "utf8");
|
||||
const { owner, repo } = context.repo;
|
||||
const issue_number = context.issue.number;
|
||||
|
||||
const comments = await github.paginate(github.rest.issues.listComments, {
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
per_page: 100,
|
||||
});
|
||||
|
||||
const existing = comments.find((comment) => comment.body?.includes(marker));
|
||||
|
||||
if (existing) {
|
||||
await github.rest.issues.updateComment({
|
||||
owner,
|
||||
repo,
|
||||
comment_id: existing.id,
|
||||
body,
|
||||
});
|
||||
} else {
|
||||
await github.rest.issues.createComment({
|
||||
owner,
|
||||
repo,
|
||||
issue_number,
|
||||
body,
|
||||
});
|
||||
}
|
||||
|
||||
test-e2e:
|
||||
name: E2E Tests
|
||||
name: E2E Tests (${{ matrix.shard }}/4)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 15
|
||||
needs: build
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
shard: [1, 2, 3, 4]
|
||||
env:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
API_KEY_SECRET: ci-test-api-key-secret-long
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npx playwright install --with-deps chromium
|
||||
- run: npm run build
|
||||
- run: npm run test:e2e
|
||||
- run: npx playwright test tests/e2e/*.spec.ts --shard=${{ matrix.shard }}/4
|
||||
|
||||
test-integration:
|
||||
name: Integration Tests
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
needs: build
|
||||
env:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
@@ -166,8 +349,8 @@ jobs:
|
||||
INITIAL_PASSWORD: ci-test-password-for-integration
|
||||
DATA_DIR: /tmp/omniroute-ci
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
@@ -182,100 +365,108 @@ jobs:
|
||||
JWT_SECRET: ci-test-secret-with-sufficient-length-for-validation
|
||||
API_KEY_SECRET: ci-test-api-key-secret-long
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
- uses: actions/checkout@v6
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npm run test:security
|
||||
|
||||
# 🔥 DASHBOARD
|
||||
ci-summary:
|
||||
name: CI Dashboard
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
needs:
|
||||
- lint
|
||||
- security
|
||||
- i18n
|
||||
- pr-test-policy
|
||||
- advanced-security
|
||||
- build
|
||||
- test-unit
|
||||
- test-coverage
|
||||
- sonarqube
|
||||
- coverage-pr-comment
|
||||
- test-e2e
|
||||
- test-integration
|
||||
- test-security
|
||||
- i18n
|
||||
|
||||
steps:
|
||||
- name: Download i18n results
|
||||
continue-on-error: true
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: i18n-*
|
||||
path: results
|
||||
merge-multiple: true
|
||||
|
||||
- name: Generate dashboard
|
||||
env:
|
||||
EVENT_NAME: ${{ github.event_name }}
|
||||
run: |
|
||||
status() {
|
||||
case "$1" in
|
||||
success) echo "🟢 PASS" ;;
|
||||
failure) echo "🔴 FAIL" ;;
|
||||
cancelled) echo "⚫ CANCELLED" ;;
|
||||
skipped) echo "⚪ SKIPPED" ;;
|
||||
*) echo "🟡 UNKNOWN" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
echo "# 🚀 CI Dashboard" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "# 🚀 CI Dashboard" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# 🔹 CORE
|
||||
echo "## 🧱 Core Checks" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Lint | $(status '${{ needs.lint.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Security Audit | $(status '${{ needs.security.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🧱 Core Checks" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Job | Status |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "|-----|--------|" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Lint | $(status '${{ needs.lint.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| PR Test Policy | $(status '${{ needs.pr-test-policy.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Advanced Security | $(status '${{ needs.advanced-security.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| SonarQube | $(status '${{ needs.sonarqube.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# 🔹 BUILD
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🏗️ Build" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Job | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-----|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Build Matrix | $(status '${{ needs.build.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "## 🏗️ Build" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Job | Status |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "|-----|--------|" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Build Matrix | $(status '${{ needs.build.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# 🔹 TESTS
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🧪 Tests" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Suite | Status |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|-------|--------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Unit | $(status '${{ needs.test-unit.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Coverage | $(status '${{ needs.test-coverage.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| E2E | $(status '${{ needs.test-e2e.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Integration | $(status '${{ needs.test-integration.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Security Tests | $(status '${{ needs.test-security.result }}') |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "## 🧪 Tests" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Suite | Status |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "|-------|--------|" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Unit | $(status '${{ needs.test-unit.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Coverage | $(status '${{ needs.test-coverage.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| PR Coverage Comment | $(status '${{ needs.coverage-pr-comment.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| E2E | $(status '${{ needs.test-e2e.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Integration | $(status '${{ needs.test-integration.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Security Tests | $(status '${{ needs.test-security.result }}') |" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
# 🔹 I18N
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "## 🌍 Translations" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "## 🌍 Translations" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
total=0
|
||||
langs=0
|
||||
|
||||
for dir in results/*; do
|
||||
file="$dir/result.txt"
|
||||
val=$(sed -r 's/\x1B\[[0-9;]*[mK]//g' "$file" | grep "Untranslated:" | awk '{print $2}')
|
||||
val=${val:-0}
|
||||
total=$((total + val))
|
||||
langs=$((langs + 1))
|
||||
done
|
||||
if [ -d results ]; then
|
||||
for file in results/*.txt; do
|
||||
[ -f "$file" ] || continue
|
||||
val=$(sed -r 's/\x1B\[[0-9;]*[mK]//g' "$file" | grep "Untranslated:" | awk '{print $2}')
|
||||
val=${val:-0}
|
||||
total=$((total + val))
|
||||
langs=$((langs + 1))
|
||||
done
|
||||
fi
|
||||
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "|--------|------|" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Languages checked | $langs |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "| Total untranslated | $total |" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Metric | Value |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "|--------|------|" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Languages checked | $langs |" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "| Total untranslated | $total |" >> "$GITHUB_STEP_SUMMARY"
|
||||
|
||||
if [ "$total" -gt 0 ]; then
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "⚠️ **Translations need attention**" >> $GITHUB_STEP_SUMMARY
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "⚠️ **Translations need attention**" >> "$GITHUB_STEP_SUMMARY"
|
||||
else
|
||||
echo "" >> $GITHUB_STEP_SUMMARY
|
||||
echo "✅ **All translations complete**" >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
echo "" >> "$GITHUB_STEP_SUMMARY"
|
||||
echo "✅ **All translations complete**" >> "$GITHUB_STEP_SUMMARY"
|
||||
fi
|
||||
|
||||
3
.github/workflows/deploy-vps.yml
vendored
3
.github/workflows/deploy-vps.yml
vendored
@@ -6,6 +6,9 @@ on:
|
||||
types: [completed]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
if: >-
|
||||
|
||||
6
.github/workflows/docker-publish.yml
vendored
6
.github/workflows/docker-publish.yml
vendored
@@ -25,15 +25,15 @@ jobs:
|
||||
IMAGE_NAME: diegosouzapw/omniroute
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && format('refs/tags/v{0}', inputs.version) || '' }}
|
||||
|
||||
- name: Set up QEMU (for multi-arch builds)
|
||||
uses: docker/setup-qemu-action@v3
|
||||
uses: docker/setup-qemu-action@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
|
||||
10
.github/workflows/electron-release.yml
vendored
10
.github/workflows/electron-release.yml
vendored
@@ -24,7 +24,7 @@ jobs:
|
||||
version: ${{ steps.validate.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -72,10 +72,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
cache: npm
|
||||
@@ -159,12 +159,12 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: release-assets
|
||||
merge-multiple: true
|
||||
|
||||
4
.github/workflows/npm-publish.yml
vendored
4
.github/workflows/npm-publish.yml
vendored
@@ -43,10 +43,10 @@ jobs:
|
||||
environment: NPM_TOKEN
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 22
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
43
.github/workflows/sync-upstream.yml
vendored
43
.github/workflows/sync-upstream.yml
vendored
@@ -1,43 +0,0 @@
|
||||
name: Sync Upstream
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Run every 6 hours
|
||||
- cron: '0 */6 * * *'
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
name: Sync with upstream
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
|
||||
- name: Fetch upstream
|
||||
run: |
|
||||
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git || true
|
||||
git fetch upstream
|
||||
git fetch origin
|
||||
|
||||
- name: Sync main branch
|
||||
run: |
|
||||
git checkout main
|
||||
git merge upstream/main --no-edit || {
|
||||
echo "Merge conflict detected. Manual intervention required."
|
||||
exit 1
|
||||
}
|
||||
|
||||
- name: Push changes
|
||||
run: git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/tombii/OmniRoute.git main
|
||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -20,9 +20,12 @@ node_modules/
|
||||
!.yarn/plugins
|
||||
!.yarn/releases
|
||||
!.yarn/versions
|
||||
.data/
|
||||
.next-playwright/
|
||||
|
||||
# testing
|
||||
coverage/
|
||||
coverage**
|
||||
|
||||
# next.js
|
||||
.next/
|
||||
@@ -56,6 +59,7 @@ next-env.d.ts
|
||||
|
||||
# data and logs
|
||||
data/
|
||||
.data/
|
||||
logs/*
|
||||
|
||||
# analysis directories (generated, not tracked)
|
||||
@@ -153,4 +157,7 @@ vscode-extension/
|
||||
typescript
|
||||
|
||||
# Gemini Antigravity agent data
|
||||
.gemini/
|
||||
.gemini/
|
||||
|
||||
# Superpowers plans/specs (internal tooling, not project code)
|
||||
docs/superpowers/
|
||||
@@ -1,3 +1,3 @@
|
||||
npx lint-staged
|
||||
node scripts/check-docs-sync.mjs
|
||||
npm run test:unit
|
||||
npm run check:any-budget:t11
|
||||
|
||||
1
.husky/pre-push
Executable file
1
.husky/pre-push
Executable file
@@ -0,0 +1 @@
|
||||
npm run test:unit
|
||||
250
.omc/project-memory.json
Normal file
250
.omc/project-memory.json
Normal file
@@ -0,0 +1,250 @@
|
||||
{
|
||||
"version": "1.0.0",
|
||||
"lastScanned": 1775016362438,
|
||||
"projectRoot": "/home/openclaw/omniroute-src",
|
||||
"techStack": {
|
||||
"languages": [
|
||||
{
|
||||
"name": "JavaScript/TypeScript",
|
||||
"version": ">=18.0.0 <24.0.0",
|
||||
"confidence": "high",
|
||||
"markers": ["package.json"]
|
||||
},
|
||||
{
|
||||
"name": "TypeScript",
|
||||
"version": null,
|
||||
"confidence": "high",
|
||||
"markers": ["tsconfig.json"]
|
||||
}
|
||||
],
|
||||
"frameworks": [
|
||||
{
|
||||
"name": "express",
|
||||
"version": "5.2.1",
|
||||
"category": "backend"
|
||||
},
|
||||
{
|
||||
"name": "next",
|
||||
"version": "16.0.10",
|
||||
"category": "fullstack"
|
||||
},
|
||||
{
|
||||
"name": "react",
|
||||
"version": "19.2.4",
|
||||
"category": "frontend"
|
||||
},
|
||||
{
|
||||
"name": "react-dom",
|
||||
"version": "19.2.4",
|
||||
"category": "frontend"
|
||||
},
|
||||
{
|
||||
"name": "@playwright/test",
|
||||
"version": "1.58.2",
|
||||
"category": "testing"
|
||||
},
|
||||
{
|
||||
"name": "vitest",
|
||||
"version": "4.0.18",
|
||||
"category": "testing"
|
||||
}
|
||||
],
|
||||
"packageManager": "npm",
|
||||
"runtime": "Node.js 18.0.024.0.0"
|
||||
},
|
||||
"build": {
|
||||
"buildCommand": "npm run build",
|
||||
"testCommand": "npm test",
|
||||
"lintCommand": "npm run lint",
|
||||
"devCommand": "npm run dev",
|
||||
"scripts": {
|
||||
"dev": "node scripts/run-next.mjs dev",
|
||||
"build": "node scripts/build-next-isolated.mjs",
|
||||
"build:cli": "node scripts/prepublish.mjs",
|
||||
"start": "node scripts/run-next.mjs start",
|
||||
"lint": "eslint .",
|
||||
"electron:dev": "concurrently \"npm run dev\" \"wait-on http://localhost:20128 && cd electron && npm run dev\"",
|
||||
"electron:build": "npm run build && cd electron && npm run build",
|
||||
"electron:build:win": "npm run build && cd electron && npm run build:win",
|
||||
"electron:build:mac": "npm run build && cd electron && npm run build:mac",
|
||||
"electron:build:linux": "npm run build && cd electron && npm run build:linux",
|
||||
"test": "node --import tsx/esm --test tests/unit/*.test.mjs",
|
||||
"test:unit": "node --import tsx/esm --test tests/unit/*.test.mjs",
|
||||
"test:plan3": "node --import tsx/esm --test tests/unit/plan3-p0.test.mjs",
|
||||
"test:fixes": "node --import tsx/esm --test tests/unit/fixes-p1.test.mjs",
|
||||
"test:security": "node --import tsx/esm --test tests/unit/security-fase01.test.mjs",
|
||||
"check:cycles": "node scripts/check-cycles.mjs",
|
||||
"check:route-validation:t06": "node scripts/check-route-validation.mjs",
|
||||
"check:any-budget:t11": "node scripts/check-t11-any-budget.mjs",
|
||||
"check:docs-sync": "node scripts/check-docs-sync.mjs",
|
||||
"typecheck:core": "tsc --pretty false -p tsconfig.typecheck-core.json",
|
||||
"typecheck:noimplicit:core": "tsc --pretty false -p tsconfig.typecheck-noimplicit-core.json",
|
||||
"test:integration": "node --import tsx/esm --test tests/integration/*.test.mjs",
|
||||
"test:e2e": "node scripts/run-playwright-tests.mjs test tests/e2e/*.spec.ts",
|
||||
"test:protocols:e2e": "node scripts/run-protocol-clients-tests.mjs",
|
||||
"test:vitest": "vitest run open-sse/mcp-server/__tests__/*.test.ts open-sse/services/autoCombo/__tests__/*.test.ts",
|
||||
"test:ecosystem": "node scripts/run-ecosystem-tests.mjs",
|
||||
"test:coverage": "c8 --exclude=tests/** --exclude=**/*.test.* --reporter=text-summary --reporter=html --reporter=json-summary --reporter=lcov --check-coverage --statements 55 --lines 55 --functions 55 --branches 60 node --import tsx/esm --test tests/unit/*.test.mjs",
|
||||
"test:coverage:legacy": "c8 --exclude=open-sse --check-coverage --lines 50 --functions 50 --branches 50 node --import tsx/esm --test tests/unit/*.test.mjs",
|
||||
"coverage:report": "c8 report --exclude=tests/** --exclude=**/*.test.* --reporter=text --reporter=text-summary --reporter=html --reporter=json-summary --reporter=lcov",
|
||||
"coverage:report:legacy": "c8 report --exclude=open-sse --reporter=text --reporter=text-summary",
|
||||
"test:all": "npm run test:unit && npm run test:vitest && npm run test:ecosystem && npm run test:e2e",
|
||||
"check": "npm run lint && npm run test",
|
||||
"prepublishOnly": "npm run build:cli",
|
||||
"postinstall": "node scripts/postinstall.mjs",
|
||||
"prepare": "husky",
|
||||
"system-info": "node scripts/system-info.mjs"
|
||||
}
|
||||
},
|
||||
"conventions": {
|
||||
"namingStyle": "camelCase",
|
||||
"importStyle": null,
|
||||
"testPattern": null,
|
||||
"fileOrganization": null
|
||||
},
|
||||
"structure": {
|
||||
"isMonorepo": true,
|
||||
"workspaces": ["open-sse"],
|
||||
"mainDirectories": ["bin", "docs", "public", "scripts", "src", "tests"],
|
||||
"gitBranches": {
|
||||
"defaultBranch": "main",
|
||||
"branchingStrategy": null
|
||||
}
|
||||
},
|
||||
"customNotes": [],
|
||||
"directoryMap": {
|
||||
"bin": {
|
||||
"path": "bin",
|
||||
"purpose": "Executable scripts",
|
||||
"fileCount": 3,
|
||||
"lastAccessed": 1775016362426,
|
||||
"keyFiles": ["mcp-server.mjs", "omniroute.mjs", "reset-password.mjs"]
|
||||
},
|
||||
"docs": {
|
||||
"path": "docs",
|
||||
"purpose": "Documentation",
|
||||
"fileCount": 14,
|
||||
"lastAccessed": 1775016362426,
|
||||
"keyFiles": [
|
||||
"A2A-SERVER.md",
|
||||
"API_REFERENCE.md",
|
||||
"ARCHITECTURE.md",
|
||||
"AUTO-COMBO.md",
|
||||
"CLI-TOOLS.md"
|
||||
]
|
||||
},
|
||||
"electron": {
|
||||
"path": "electron",
|
||||
"purpose": null,
|
||||
"fileCount": 5,
|
||||
"lastAccessed": 1775016362431,
|
||||
"keyFiles": ["README.md", "main.js", "package.json", "preload.js", "types.d.ts"]
|
||||
},
|
||||
"images": {
|
||||
"path": "images",
|
||||
"purpose": null,
|
||||
"fileCount": 1,
|
||||
"lastAccessed": 1775016362434,
|
||||
"keyFiles": ["omniroute.png"]
|
||||
},
|
||||
"logs": {
|
||||
"path": "logs",
|
||||
"purpose": null,
|
||||
"fileCount": 3,
|
||||
"lastAccessed": 1775016362434,
|
||||
"keyFiles": ["build_clean_tools.log", "build_debug.log", "build_force_clean.log"]
|
||||
},
|
||||
"open-sse": {
|
||||
"path": "open-sse",
|
||||
"purpose": null,
|
||||
"fileCount": 5,
|
||||
"lastAccessed": 1775016362434,
|
||||
"keyFiles": ["index.ts", "package.json", "tsconfig.json", "types.d.ts"]
|
||||
},
|
||||
"public": {
|
||||
"path": "public",
|
||||
"purpose": "Public files",
|
||||
"fileCount": 3,
|
||||
"lastAccessed": 1775016362435,
|
||||
"keyFiles": ["apple-touch-icon.svg", "favicon.svg", "icon-192.svg"]
|
||||
},
|
||||
"scripts": {
|
||||
"path": "scripts",
|
||||
"purpose": "Build/utility scripts",
|
||||
"fileCount": 23,
|
||||
"lastAccessed": 1775016362435,
|
||||
"keyFiles": [
|
||||
"bootstrap-env.mjs",
|
||||
"build-next-isolated.mjs",
|
||||
"check-cycles.mjs",
|
||||
"check-docs-sync.mjs",
|
||||
"check-route-validation.mjs"
|
||||
]
|
||||
},
|
||||
"src": {
|
||||
"path": "src",
|
||||
"purpose": "Source code",
|
||||
"fileCount": 4,
|
||||
"lastAccessed": 1775016362435,
|
||||
"keyFiles": ["instrumentation-node.ts", "instrumentation.ts", "proxy.ts", "server-init.ts"]
|
||||
},
|
||||
"tests": {
|
||||
"path": "tests",
|
||||
"purpose": "Test files",
|
||||
"fileCount": 0,
|
||||
"lastAccessed": 1775016362435,
|
||||
"keyFiles": []
|
||||
},
|
||||
"electron/assets": {
|
||||
"path": "electron/assets",
|
||||
"purpose": "Static assets",
|
||||
"fileCount": 4,
|
||||
"lastAccessed": 1775016362436,
|
||||
"keyFiles": ["icon.icns", "icon.ico", "icon.png"]
|
||||
},
|
||||
"open-sse/config": {
|
||||
"path": "open-sse/config",
|
||||
"purpose": "Configuration files",
|
||||
"fileCount": 17,
|
||||
"lastAccessed": 1775016362436,
|
||||
"keyFiles": ["audioRegistry.ts", "cliFingerprints.ts", "codexInstructions.ts"]
|
||||
},
|
||||
"open-sse/services": {
|
||||
"path": "open-sse/services",
|
||||
"purpose": "Business logic services",
|
||||
"fileCount": 35,
|
||||
"lastAccessed": 1775016362437,
|
||||
"keyFiles": ["accountFallback.ts", "accountSelector.ts", "apiKeyRotator.ts"]
|
||||
},
|
||||
"src/app": {
|
||||
"path": "src/app",
|
||||
"purpose": "Application code",
|
||||
"fileCount": 7,
|
||||
"lastAccessed": 1775016362438,
|
||||
"keyFiles": ["error.tsx", "global-error.tsx", "globals.css"]
|
||||
},
|
||||
"src/lib": {
|
||||
"path": "src/lib",
|
||||
"purpose": "Library code",
|
||||
"fileCount": 30,
|
||||
"lastAccessed": 1775016362438,
|
||||
"keyFiles": ["apiBridgeServer.ts", "apiKeyExposure.ts", "cacheControlSettings.ts"]
|
||||
},
|
||||
"src/middleware": {
|
||||
"path": "src/middleware",
|
||||
"purpose": "Middleware",
|
||||
"fileCount": 1,
|
||||
"lastAccessed": 1775016362438,
|
||||
"keyFiles": ["promptInjectionGuard.ts"]
|
||||
},
|
||||
"src/models": {
|
||||
"path": "src/models",
|
||||
"purpose": "Data models",
|
||||
"fileCount": 1,
|
||||
"lastAccessed": 1775016362438,
|
||||
"keyFiles": ["index.ts"]
|
||||
}
|
||||
},
|
||||
"hotPaths": [],
|
||||
"userDirectives": []
|
||||
}
|
||||
8
.omc/sessions/53c002c3-36a6-47c3-a52d-a8f756c264eb.json
Normal file
8
.omc/sessions/53c002c3-36a6-47c3-a52d-a8f756c264eb.json
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"session_id": "53c002c3-36a6-47c3-a52d-a8f756c264eb",
|
||||
"ended_at": "2026-04-01T04:06:04.924Z",
|
||||
"reason": "prompt_input_exit",
|
||||
"agents_spawned": 0,
|
||||
"agents_completed": 0,
|
||||
"modes_used": []
|
||||
}
|
||||
1
.playwright-mcp/console-2026-04-04T08-03-37-016Z.log
Normal file
1
.playwright-mcp/console-2026-04-04T08-03-37-016Z.log
Normal file
@@ -0,0 +1 @@
|
||||
[ 32698ms] [ERROR] Failed to load resource: the server responded with a status of 404 (Not Found) @ http://localhost:20130/dashboard/usage?_rsc=18t7j:0
|
||||
158
.playwright-mcp/page-2026-04-04T08-03-38-145Z.yml
Normal file
158
.playwright-mcp/page-2026-04-04T08-03-38-145Z.yml
Normal file
@@ -0,0 +1,158 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- link "Skip to content" [ref=e2] [cursor=pointer]:
|
||||
- /url: "#main-content"
|
||||
- generic [ref=e3]:
|
||||
- complementary [ref=e5]:
|
||||
- link "Skip to content" [ref=e6] [cursor=pointer]:
|
||||
- /url: "#main-content"
|
||||
- link "OmniRoute v3.5.0" [ref=e12] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- img [ref=e14]
|
||||
- generic [ref=e26]:
|
||||
- heading "OmniRoute" [level=1] [ref=e27]
|
||||
- generic [ref=e28]: v3.5.0
|
||||
- navigation "Main navigation" [ref=e29]:
|
||||
- generic [ref=e30]:
|
||||
- link "home Home" [ref=e31] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- generic [ref=e32]: home
|
||||
- generic [ref=e33]: Home
|
||||
- link "api Endpoints" [ref=e34] [cursor=pointer]:
|
||||
- /url: /dashboard/endpoint
|
||||
- generic [ref=e35]: api
|
||||
- generic [ref=e36]: Endpoints
|
||||
- link "vpn_key API Manager" [ref=e37] [cursor=pointer]:
|
||||
- /url: /dashboard/api-manager
|
||||
- generic [ref=e38]: vpn_key
|
||||
- generic [ref=e39]: API Manager
|
||||
- link "dns Providers" [ref=e40] [cursor=pointer]:
|
||||
- /url: /dashboard/providers
|
||||
- generic [ref=e41]: dns
|
||||
- generic [ref=e42]: Providers
|
||||
- link "layers Combos" [ref=e43] [cursor=pointer]:
|
||||
- /url: /dashboard/combos
|
||||
- generic [ref=e44]: layers
|
||||
- generic [ref=e45]: Combos
|
||||
- link "auto_awesome Auto Combo" [ref=e46] [cursor=pointer]:
|
||||
- /url: /dashboard/auto-combo
|
||||
- generic [ref=e47]: auto_awesome
|
||||
- generic [ref=e48]: Auto Combo
|
||||
- link "account_balance_wallet Costs" [ref=e49] [cursor=pointer]:
|
||||
- /url: /dashboard/costs
|
||||
- generic [ref=e50]: account_balance_wallet
|
||||
- generic [ref=e51]: Costs
|
||||
- link "analytics Analytics" [ref=e52] [cursor=pointer]:
|
||||
- /url: /dashboard/analytics
|
||||
- generic [ref=e53]: analytics
|
||||
- generic [ref=e54]: Analytics
|
||||
- link "tune Limits & Quotas" [ref=e55] [cursor=pointer]:
|
||||
- /url: /dashboard/limits
|
||||
- generic [ref=e56]: tune
|
||||
- generic [ref=e57]: Limits & Quotas
|
||||
- link "cached Cache" [ref=e58] [cursor=pointer]:
|
||||
- /url: /dashboard/cache
|
||||
- generic [ref=e59]: cached
|
||||
- generic [ref=e60]: Cache
|
||||
- link "perm_media Media" [ref=e61] [cursor=pointer]:
|
||||
- /url: /dashboard/cache/media
|
||||
- generic [ref=e62]: perm_media
|
||||
- generic [ref=e63]: Media
|
||||
- generic [ref=e64]:
|
||||
- paragraph [ref=e65]: CLI
|
||||
- link "terminal Tools" [ref=e66] [cursor=pointer]:
|
||||
- /url: /dashboard/cli-tools
|
||||
- generic [ref=e67]: terminal
|
||||
- generic [ref=e68]: Tools
|
||||
- link "smart_toy Agents" [ref=e69] [cursor=pointer]:
|
||||
- /url: /dashboard/agents
|
||||
- generic [ref=e70]: smart_toy
|
||||
- generic [ref=e71]: Agents
|
||||
- link "psychology Memory" [ref=e72] [cursor=pointer]:
|
||||
- /url: /dashboard/memory
|
||||
- generic [ref=e73]: psychology
|
||||
- generic [ref=e74]: Memory
|
||||
- link "auto_fix_high Skills" [ref=e75] [cursor=pointer]:
|
||||
- /url: /dashboard/skills
|
||||
- generic [ref=e76]: auto_fix_high
|
||||
- generic [ref=e77]: Skills
|
||||
- generic [ref=e78]:
|
||||
- paragraph [ref=e79]: System
|
||||
- link "health_and_safety Health" [ref=e80] [cursor=pointer]:
|
||||
- /url: /dashboard/health
|
||||
- generic [ref=e81]: health_and_safety
|
||||
- generic [ref=e82]: Health
|
||||
- link "description Logs" [ref=e83] [cursor=pointer]:
|
||||
- /url: /dashboard/logs
|
||||
- generic [ref=e84]: description
|
||||
- generic [ref=e85]: Logs
|
||||
- link "history Audit Log" [ref=e86] [cursor=pointer]:
|
||||
- /url: /dashboard/audit
|
||||
- generic [ref=e87]: history
|
||||
- generic [ref=e88]: Audit Log
|
||||
- link "settings Settings" [ref=e89] [cursor=pointer]:
|
||||
- /url: /dashboard/settings
|
||||
- generic [ref=e90]: settings
|
||||
- generic [ref=e91]: Settings
|
||||
- generic [ref=e92]:
|
||||
- paragraph [ref=e93]: Help
|
||||
- link "menu_book Docs" [ref=e94] [cursor=pointer]:
|
||||
- /url: /docs
|
||||
- generic [ref=e95]: menu_book
|
||||
- generic [ref=e96]: Docs
|
||||
- link "bug_report Issues" [ref=e97] [cursor=pointer]:
|
||||
- /url: https://github.com/diegosouzapw/OmniRoute/issues
|
||||
- generic [ref=e98]: bug_report
|
||||
- generic [ref=e99]: Issues
|
||||
- generic [ref=e100]:
|
||||
- button "restart_alt Restart" [ref=e101]:
|
||||
- generic: restart_alt
|
||||
- text: Restart
|
||||
- button "power_settings_new Shutdown" [ref=e102]:
|
||||
- generic: power_settings_new
|
||||
- text: Shutdown
|
||||
- main [ref=e103]:
|
||||
- generic [ref=e104]:
|
||||
- button "menu" [ref=e106]:
|
||||
- generic: menu
|
||||
- generic [ref=e107]:
|
||||
- button "🇺🇸 EN expand_more" [ref=e109]:
|
||||
- generic [ref=e110]: 🇺🇸
|
||||
- generic [ref=e111]: EN
|
||||
- generic: expand_more
|
||||
- button "Switch to dark mode" [ref=e112]:
|
||||
- generic: dark_mode
|
||||
- button "logout" [ref=e113]:
|
||||
- generic: logout
|
||||
- generic [ref=e115]:
|
||||
- navigation "Breadcrumb" [ref=e116]:
|
||||
- link "Dashboard" [ref=e118] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- generic [ref=e119]:
|
||||
- generic [ref=e120]: ›
|
||||
- generic [ref=e121]: Onboarding
|
||||
- generic [ref=e123]:
|
||||
- generic [ref=e124]:
|
||||
- generic [ref=e126]: "1"
|
||||
- generic [ref=e129]: "2"
|
||||
- generic [ref=e132]: "3"
|
||||
- generic [ref=e135]: "4"
|
||||
- generic [ref=e138]: "5"
|
||||
- generic [ref=e139]:
|
||||
- generic [ref=e140]:
|
||||
- generic [ref=e141]: waving_hand
|
||||
- heading "Welcome" [level=2] [ref=e142]
|
||||
- generic [ref=e144]:
|
||||
- paragraph [ref=e145]: OmniRoute is your local AI API proxy. It routes requests to multiple AI providers with load balancing, failover, and usage tracking.
|
||||
- generic [ref=e146]:
|
||||
- generic [ref=e147]:
|
||||
- generic [ref=e148]: swap_horiz
|
||||
- text: Multi-Provider
|
||||
- generic [ref=e149]:
|
||||
- generic [ref=e150]: monitoring
|
||||
- text: Usage Tracking
|
||||
- generic [ref=e151]:
|
||||
- generic [ref=e152]: shield
|
||||
- text: API Key Mgmt
|
||||
- button "Get Started" [ref=e155] [cursor=pointer]
|
||||
- button "Skip wizard entirely" [ref=e157] [cursor=pointer]
|
||||
- alert [ref=e158]
|
||||
1011
.playwright-mcp/page-2026-04-04T08-04-15-839Z.yml
Normal file
1011
.playwright-mcp/page-2026-04-04T08-04-15-839Z.yml
Normal file
File diff suppressed because it is too large
Load Diff
132
.playwright-mcp/page-2026-04-04T08-04-46-313Z.yml
Normal file
132
.playwright-mcp/page-2026-04-04T08-04-46-313Z.yml
Normal file
@@ -0,0 +1,132 @@
|
||||
- generic [active] [ref=e1]:
|
||||
- link "Skip to content" [ref=e2] [cursor=pointer]:
|
||||
- /url: "#main-content"
|
||||
- generic [ref=e3]:
|
||||
- complementary [ref=e5]:
|
||||
- link "Skip to content" [ref=e6] [cursor=pointer]:
|
||||
- /url: "#main-content"
|
||||
- link "OmniRoute v3.5.0" [ref=e12] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- img [ref=e14]
|
||||
- generic [ref=e26]:
|
||||
- heading "OmniRoute" [level=1] [ref=e27]
|
||||
- generic [ref=e28]: v3.5.0
|
||||
- navigation "Main navigation" [ref=e29]:
|
||||
- generic [ref=e30]:
|
||||
- link "home Home" [ref=e31] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- generic [ref=e32]: home
|
||||
- generic [ref=e33]: Home
|
||||
- link "api Endpoints" [ref=e34] [cursor=pointer]:
|
||||
- /url: /dashboard/endpoint
|
||||
- generic [ref=e35]: api
|
||||
- generic [ref=e36]: Endpoints
|
||||
- link "vpn_key API Manager" [ref=e37] [cursor=pointer]:
|
||||
- /url: /dashboard/api-manager
|
||||
- generic [ref=e38]: vpn_key
|
||||
- generic [ref=e39]: API Manager
|
||||
- link "dns Providers" [ref=e40] [cursor=pointer]:
|
||||
- /url: /dashboard/providers
|
||||
- generic [ref=e41]: dns
|
||||
- generic [ref=e42]: Providers
|
||||
- link "layers Combos" [ref=e43] [cursor=pointer]:
|
||||
- /url: /dashboard/combos
|
||||
- generic [ref=e44]: layers
|
||||
- generic [ref=e45]: Combos
|
||||
- link "auto_awesome Auto Combo" [ref=e46] [cursor=pointer]:
|
||||
- /url: /dashboard/auto-combo
|
||||
- generic [ref=e47]: auto_awesome
|
||||
- generic [ref=e48]: Auto Combo
|
||||
- link "account_balance_wallet Costs" [ref=e49] [cursor=pointer]:
|
||||
- /url: /dashboard/costs
|
||||
- generic [ref=e50]: account_balance_wallet
|
||||
- generic [ref=e51]: Costs
|
||||
- link "analytics Analytics" [ref=e52] [cursor=pointer]:
|
||||
- /url: /dashboard/analytics
|
||||
- generic [ref=e53]: analytics
|
||||
- generic [ref=e54]: Analytics
|
||||
- link "tune Limits & Quotas" [ref=e55] [cursor=pointer]:
|
||||
- /url: /dashboard/limits
|
||||
- generic [ref=e56]: tune
|
||||
- generic [ref=e57]: Limits & Quotas
|
||||
- link "cached Cache" [ref=e58] [cursor=pointer]:
|
||||
- /url: /dashboard/cache
|
||||
- generic [ref=e59]: cached
|
||||
- generic [ref=e60]: Cache
|
||||
- link "perm_media Media" [ref=e61] [cursor=pointer]:
|
||||
- /url: /dashboard/cache/media
|
||||
- generic [ref=e62]: perm_media
|
||||
- generic [ref=e63]: Media
|
||||
- generic [ref=e64]:
|
||||
- paragraph [ref=e65]: CLI
|
||||
- link "terminal Tools" [ref=e66] [cursor=pointer]:
|
||||
- /url: /dashboard/cli-tools
|
||||
- generic [ref=e67]: terminal
|
||||
- generic [ref=e68]: Tools
|
||||
- link "smart_toy Agents" [ref=e69] [cursor=pointer]:
|
||||
- /url: /dashboard/agents
|
||||
- generic [ref=e70]: smart_toy
|
||||
- generic [ref=e71]: Agents
|
||||
- link "psychology Memory" [ref=e72] [cursor=pointer]:
|
||||
- /url: /dashboard/memory
|
||||
- generic [ref=e73]: psychology
|
||||
- generic [ref=e74]: Memory
|
||||
- link "auto_fix_high Skills" [ref=e75] [cursor=pointer]:
|
||||
- /url: /dashboard/skills
|
||||
- generic [ref=e76]: auto_fix_high
|
||||
- generic [ref=e77]: Skills
|
||||
- generic [ref=e78]:
|
||||
- paragraph [ref=e79]: System
|
||||
- link "health_and_safety Health" [ref=e80] [cursor=pointer]:
|
||||
- /url: /dashboard/health
|
||||
- generic [ref=e81]: health_and_safety
|
||||
- generic [ref=e82]: Health
|
||||
- link "description Logs" [ref=e83] [cursor=pointer]:
|
||||
- /url: /dashboard/logs
|
||||
- generic [ref=e84]: description
|
||||
- generic [ref=e85]: Logs
|
||||
- link "history Audit Log" [ref=e86] [cursor=pointer]:
|
||||
- /url: /dashboard/audit
|
||||
- generic [ref=e87]: history
|
||||
- generic [ref=e88]: Audit Log
|
||||
- link "settings Settings" [ref=e89] [cursor=pointer]:
|
||||
- /url: /dashboard/settings
|
||||
- generic [ref=e90]: settings
|
||||
- generic [ref=e91]: Settings
|
||||
- generic [ref=e92]:
|
||||
- paragraph [ref=e93]: Help
|
||||
- link "menu_book Docs" [ref=e94] [cursor=pointer]:
|
||||
- /url: /docs
|
||||
- generic [ref=e95]: menu_book
|
||||
- generic [ref=e96]: Docs
|
||||
- link "bug_report Issues" [ref=e97] [cursor=pointer]:
|
||||
- /url: https://github.com/diegosouzapw/OmniRoute/issues
|
||||
- generic [ref=e98]: bug_report
|
||||
- generic [ref=e99]: Issues
|
||||
- generic [ref=e100]:
|
||||
- button "restart_alt Restart" [ref=e101]:
|
||||
- generic: restart_alt
|
||||
- text: Restart
|
||||
- button "power_settings_new Shutdown" [ref=e102]:
|
||||
- generic: power_settings_new
|
||||
- text: Shutdown
|
||||
- main [ref=e103]:
|
||||
- generic [ref=e104]:
|
||||
- button "menu" [ref=e106]:
|
||||
- generic: menu
|
||||
- generic [ref=e107]:
|
||||
- button "🇺🇸 EN expand_more" [ref=e109]:
|
||||
- generic [ref=e110]: 🇺🇸
|
||||
- generic [ref=e111]: EN
|
||||
- generic: expand_more
|
||||
- button "Switch to dark mode" [ref=e112]:
|
||||
- generic: dark_mode
|
||||
- button "logout" [ref=e113]:
|
||||
- generic: logout
|
||||
- navigation "Breadcrumb" [ref=e116]:
|
||||
- link "Dashboard" [ref=e118] [cursor=pointer]:
|
||||
- /url: /dashboard
|
||||
- generic [ref=e119]:
|
||||
- generic [ref=e120]: ›
|
||||
- generic [ref=e121]: Providers
|
||||
- alert [ref=e135]
|
||||
@@ -63,10 +63,17 @@ npm run test:protocols:e2e
|
||||
# Ecosystem compatibility tests
|
||||
npm run test:ecosystem
|
||||
|
||||
# Coverage (55% min thresholds — statements, lines, functions; 60% branches)
|
||||
# Coverage (60% minimum for statements, lines, functions, and branches)
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
### PR Coverage Policy
|
||||
|
||||
- `npm run test:coverage` is the PR coverage gate in CI.
|
||||
- The repository minimum is **60%** for statements, lines, functions, and branches.
|
||||
- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must include or update automated tests in the same PR.
|
||||
- For agent-driven review or coding flows: if coverage is below the gate or source changes ship without tests, do not stop at reporting. Add or update tests first, rerun the gate, and only then ask for confirmation.
|
||||
|
||||
---
|
||||
|
||||
## Code Style Guidelines
|
||||
|
||||
196
CHANGELOG.md
196
CHANGELOG.md
@@ -4,6 +4,187 @@
|
||||
|
||||
---
|
||||
|
||||
## [3.5.3] - 2026-04-07
|
||||
|
||||
### Security
|
||||
|
||||
- **Vulnerabilities:** Fully remediated 12 High-Severity CodeQL vulnerabilities by migrating from Math.random to `crypto.randomUUID()`, wrapping SSE injection points with aggressive backslash escaping, sanitizing trailing HTTP fragments, and enforcing rigid SSRF HTTP verification schemes across internal routes.
|
||||
- **Dependencies:** Upgraded Next.js to `^16.2.2` and Vite to `>=8.0.5` resolving critical DoS, arbitrary file reads and CSRF vectors in the build/server environments.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **E2E Stability:** Eliminated extreme CI unreliability and transient test timeouts (Playwright) by propagating internal standalone `_next/static` assets properly and refactoring deep UI interactions inside defensive `expect().toPass()` loops.
|
||||
- **Middleware:** Resolved infinite redirect loop on dashboard for fresh instances when requireLogin is disabled.
|
||||
- **Core Fallbacks:** Preserved primary failure contexts and enhanced Edge-case error handling pipelines across chat and fallback loops.
|
||||
- **Proxy/Hooks:** Optimized local git hooks, normalized token coverage endpoints into `/coverage`, and guarded GLM region lookups.
|
||||
|
||||
### 🛠️ Maintenance
|
||||
|
||||
- **CI/CD Stabilization:** Prevented random GitHub Runner freezes by decoupling sharded processes, adjusting test concurrencies, unref-ing active connections on server teardown, and strictly capping job timeout durations.
|
||||
|
||||
### Documentation
|
||||
|
||||
- **I18n Engine:** Synchronized and pushed deep Machine Translation updates across all 32 natively-supported languages (682 translation nodes aligned).
|
||||
|
||||
### Coverage
|
||||
|
||||
- **Testing:** Consolidated the workspace test coverage framework hitting 92.1% statement line coverage, with new rigid unit-tests matching API key policies and tool scopes.
|
||||
|
||||
---
|
||||
|
||||
## [3.5.2] — 2026-04-05
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Qoder API Native Integration:** Completely refactored the Qoder Executor to bypass the legacy COSY AES/RSA encryption algorithm, routing directly into the native DashScope OpenAi-compatible URL. Eliminates complex dependencies on Node `crypto` modules while improving stream fidelity.
|
||||
- **Resilience Engine Overhaul:** Integrated context overflow graceful fallbacks, proactive OAuth token detection, and empty-content emission prevention (#990).
|
||||
- **Context-Optimized Routing Strategy:** Added new intelligent routing capability to natively maximize context windows in automated combo deployments (#990).
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Responses API Stream Corruption:** Fixed deep-cloning corruption where Anthropic/OpenAI translation boundaries stripped `response.` specific SSE prefixes from streaming boundaries (#992).
|
||||
- **Claude Cache Passthrough Alignment:** Aligned CC-Compatible cache markers consistently with upstream Client Pass-Through mode preserving prompt caching.
|
||||
- **Turbopack Memory Leak:** Pinned Next.js to strict `16.0.10` preventing memory leaks and build staleness from recent upstream Turbopack hashed module regressions (#987).
|
||||
|
||||
---
|
||||
|
||||
## [3.5.1] — 2026-04-04
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Models.dev Integration:** Integrated models.dev as the authoritative runtime source for model pricing, capabilities, and specifications, overriding hardcoded prices. Includes a settings UI to manage sync intervals, translation strings for all 30 languages, and robust test coverage.
|
||||
- **Provider Native Capabilities:** Added support for declaring and checking native API features (e.g. `systemInstructions_supported`) preventing failures by sanitizing invalid roles. Currently configured for Gemini Base and Antigravity OAuth providers.
|
||||
- **API Provider Advanced Settings:** Added per-connection custom `User-Agent` overrides for API-key provider connections. The override is stored in `providerSpecificData.customUserAgent` and now applies to validation probes and upstream execution requests.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Qwen OAuth Reliability:** Resolved a series of OAuth integration issues including a 400 Bad Request blocker on expired tokens, fallback generation for parsing OIDC `access_token` properties when `id_token` is omitted, model catalog discovery errors, and strict filtering of `X-Dashscope-*` headers to avoid 400 rejection from OpenAI-compatible endpoints.
|
||||
|
||||
## [3.5.0] — 2026-04-03
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Auto-Combo & Routing:** Completed native CRUD lifecycle integration for the advanced Auto-Combo engine (#955).
|
||||
- **Core Operations:** Fixed missing translations for new native Auto-Combos options (#955).
|
||||
- **Security Validation:** Disabled SQLite auto-backup tasks natively during unit test CI execution to explicitly resolve Node 22 Event Loop hanging memory leaks (#956).
|
||||
- **Ecosystem Proxies:** Completed explicit integration mapping model synchronization schedulers, OAuth cycles, and Token Check refreshes safely through OmniRoute's native system upstream proxies (#953).
|
||||
- **MCP Extensibility:** Added and successfully registered the new `omniroute_web_search` MCP framework tool out of beta into production schemas (#951).
|
||||
- **Tokens Buffer Logic:** Added runtime configuration limits extending configurable input/output token buffers for precise Usage Tracking metrics (#959).
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **CodeQL Remediation:** Fully resolved and secured critical string indexing operations preventing Server-Side Request Forgery (SSRF) arrays indexing heuristics alongside polynomial algorithmic backtracking (ReDoS) inside deep proxy dispatcher modules.
|
||||
- **Crypto Hashes:** Replaced weak unverified legacy OAuth 1.0 hashes with robust HMAC-SHA-256 standard validation primitives ensuring tight access controls.
|
||||
- **API Boundary Protection:** Correctly verified and mapped structural route protections enforcing strict `isAuthenticated()` middleware logic covering newer dynamic endpoints targeting settings manipulation and native skills loading.
|
||||
- **CLI Ecosystem Compat:** Resolved broken native runtime parser bindings crashing `where` environment detectors strictly over `.cmd/.exe` edge cases gracefully for external plugins (#969).
|
||||
- **Cache Architecture:** Refactored exact Analytics and System Settings dashboard parameters layout structure caching to maintain stable re-hydration persistence cycles resolving visual unaligned state flashes (#952).
|
||||
- **Claude Caching Standards:** Normalized and accurately strictly preserved critical ephemeral block markers `ephemeral` caching TTL orders for downstream nodes enforcing standard compatible CC requests mapping cleanly without dropped metrics (#948).
|
||||
- **Internal Aliases Auth:** Simplified internal runtime mappings normalizing Codex credential payload lookups inside global translation parameters resolving 401 unauthenticated drops (#958).
|
||||
|
||||
### 🛠️ Maintenance
|
||||
|
||||
- **UI Discoverability:** Correctly adjusted layout categorizations explicitly separating free tier providers logic improving UX sorting flows inside the general API registry pages (#950).
|
||||
- **Deployment Topology:** Unified Docker deployment artifacts ensuring the root `fly.toml` matches expected cloud instance parameters out-of-the-box natively handling automated deployments scaling properly.
|
||||
- **Development Tooling:** Decoupled `LKGP` runtime parameters into explicit DB layer abstraction caching utilities ensuring strict test isolation coverage for core caching layers safely.
|
||||
|
||||
---
|
||||
|
||||
## [3.4.9] — 2026-04-03
|
||||
|
||||
### Features & Refactoring
|
||||
|
||||
- **Dashboard Auto-Combo Panel:** Completely refactored the `/dashboard/auto-combo` UI to seamlessly integrate with native Dashboard Cards and standardized visual padding/headers. Added dynamic visual progress bars mapping model selection weight mechanisms.
|
||||
- **Settings Routing Sync:** Fully exposed advanced routing `priority` and `weighted` schema targets internally inside global settings fallback lists.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- **Memory & Skills Locale Nodes:** Resolved empty rendering tags for Memory and Skills options directly inside global settings views by wiring all `settings.*` mapping values internally into `en.json` (also mapped implicitly for cross-translation tools).
|
||||
|
||||
### Internal Integrations
|
||||
|
||||
- Integrated PR #946 — fix: preserve Claude Code compatibility in responses conversion
|
||||
- Integrated PR #944 — fix(gemini): preserve thought signatures across antigravity tool calls
|
||||
- Integrated PR #943 — fix: restore GitHub Copilot body
|
||||
- Integrated PR #942 — Fix cc-compatible cache markers
|
||||
- Integrated PR #941 — refactor(auth): improve NVIDIA alias lookup + add LKGP error logging
|
||||
- Integrated PR #939 — Restore Claude OAuth localhost callback handling
|
||||
- _(Note: PR #934 was omitted from 3.4.9 cycle to prevent core conflict regressions)_
|
||||
|
||||
---
|
||||
|
||||
## [3.4.8] — 2026-04-03
|
||||
|
||||
### Security
|
||||
|
||||
- Fully remediated all outstanding Github Advanced Security (CodeQL) findings and Dependabot alerts.
|
||||
- Fixed insecure randomness vulnerabilities by migrating from `Math.random` to `crypto.randomUUID()`.
|
||||
- Secured shell commands in automated scripts from string injection.
|
||||
- Migrated vulnerable catastrophic backtracking RegEx parsing patterns in chat/translation pipelines.
|
||||
- Enhanced output sanitization controls inside React UI components and Server Sent Events (SSE) tag injection.
|
||||
|
||||
---
|
||||
|
||||
## [3.4.7] — 2026-04-03
|
||||
|
||||
### Features
|
||||
|
||||
- Added `Cryptography` node to Monitoring and MCP health checks (#798)
|
||||
- Hardened model-catalog route permissions mapping (`/models`) (#781)
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
- Fixed Claude OAuth token refreshes failing to preserve cache contexts (#937)
|
||||
- Fixed CC-Compatible provider errors rendering cached models unreachable (#937)
|
||||
- Fixed GitHub Executor errors related to invalid context arrays (#937)
|
||||
- Fixed NPM-installed CLI tools healthcheck failures on Windows (#935)
|
||||
- Fixed payload translation dropping valid content due to invalid API fields (#927)
|
||||
- Fixed runtime crash in Node 25 regarding API key execution (#867)
|
||||
- Fixed MCP standalone module-resolution (`ERR_MODULE_NOT_FOUND`) via `esbuild` (#936)
|
||||
- Fixed NVIDIA NIM routing credential resolution alias mismatch (#931)
|
||||
|
||||
### Security
|
||||
|
||||
- Added safe strict input boundary protection against raw `shell: true` remote-code execution injections.
|
||||
|
||||
---
|
||||
|
||||
## [3.4.6] - 2026-04-02
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **Providers:** Registered new image, video, and audio generation providers from the community-requested list (#926).
|
||||
- **Dashboard UI:** Added standalone sidebar navigation for the new Memory and Skills modules (#926).
|
||||
- **i18n:** Added translation strings and layout mappings across 30 languages for the Memory and Skills namespaces.
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **Resilience:** Prevented the proxy Circuit Breaker from becoming stuck in an OPEN state indefinitely by handling direct transitions to CLOSED state inside fallback combo paths (#930).
|
||||
- **Protocol Translation:** Patched the streaming transformer to sanitize response blocks based on the expected _source_ protocol rather than the provider _target_ protocol, fixing Anthropics models wrapped in OpenAI payloads crashing Claude Code (#929).
|
||||
- **API Specs & Gemini:** Fixed `thought_signature` parsing in `openai-to-gemini` and `claude-to-gemini` translators, preventing HTTP 400 errors across all Gemini 3 API tool-calls.
|
||||
- **Providers:** Cleaned up non-OpenAI-compatible endpoints preventing valid upstream connections (#926).
|
||||
- **Cache Trends:** Fixed an invalid property mapping data mismatch causing Cache Trends UI charts to crash, and extracted redundant cache metric widgets (#926).
|
||||
|
||||
---
|
||||
|
||||
## [3.4.5] - 2026-04-02
|
||||
|
||||
### ✨ New Features
|
||||
|
||||
- **CLIProxyAPI Ecosystem Integration:** Added the `cliproxyapi` executor with built-in module-level caching and proxy routing. Introduced a comprehensive Version Manager service to automatically test health, download binaries from GitHub, spawn isolated background processes, and cleanly manage the lifecycle of external CLI tools directly through the UI. Includes DB tables for proxy configuration to enable automatic SSRF-gated cross-routing of external OpenAI requests via the local CLI tool layer (#914, #915, #916).
|
||||
- **Qoder PAT Support:** Integrated Personal Access Tokens (PAT) support directly via the local `qodercli` transport instead of legacy remote `.cn` browser configurations (#913).
|
||||
- **Gemini 3.1 Pro Preview (GitHub):** Added `gemini-3.1-pro-preview` canonical explicit model support natively into the GitHub Copilot provider while preserving older routing aliases (#924).
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **GitHub Copilot Token Stability:** Repaired the Copilot token refresh loop where stale tokens weren't deep-merged into DB, and removed `reasoning_text` fields that were fatally breaking downstream Anthropic block conversions for multi-turn chats (#923).
|
||||
- **Global Timeout Matrix:** Centralized and parameterized request timeouts explicitly from `REQUEST_TIMEOUT_MS` to prevent hidden (~300s) default fetch buffers prematurely cutting off long-lived SSE streaming responses from heavy reasoning models (#918).
|
||||
- **Cloudflare Quick Tunnels State:** Fixed a severe state inconsistency where restarted OmniRoute instances erroneously showed destroyed tunnels as active, and defaulted cloudflared tunneling to `HTTP/2` to eliminate UDP receive buffer log spam (#925).
|
||||
- **i18n Translation Overhaul (Czech & Hindi):** Fixed Hindi code from DEPRECATED `in.json` to canonical `hi.json`, overhauled Czech text mappings, extracted `untranslatable-keys.json` to fix CI/CD false-positive validations, and generated comprehensive `I18N.md` docs to guide translators (#912).
|
||||
- **Tokens Provider Recovery:** Fixed Qwen losing specific `resourceUrl` endpoints after automatic health-check token refreshes because of missing DB deep merges (#917).
|
||||
- **CC Compatible UX & Streaming:** Unified the Add CC/OpenAI/Anthropic compatible actions around the Anthropic UI treatment, forced CC-compatible upstream requests to use SSE while still returning streaming or non-streaming responses based on the client request, removed CC model-list configuration/import support in favor of an explicit unsupported-model-listing error, and made CC-compatible Available Models mirror the OAuth Claude Code registry list (#921).
|
||||
|
||||
---
|
||||
|
||||
## [3.4.4] - 2026-04-02
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
@@ -1248,7 +1429,7 @@ OmniRoute now automatically refreshes model lists for connected providers every
|
||||
#### Developer Experience
|
||||
|
||||
- **#489 — Antigravity:** Missing `googleProjectId` returns a structured 422 error with reconnect guidance instead of a cryptic crash.
|
||||
- **#510 — Windows paths:** MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\\Program Files\\...` automatically.
|
||||
- **#510 — Windows paths:** MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\Program Files\...` automatically.
|
||||
- **#492 — CLI startup:** `omniroute` CLI now detects `mise`/`nvm`-managed Node when `app/server.js` is missing and shows targeted fix instructions.
|
||||
|
||||
---
|
||||
@@ -1370,7 +1551,7 @@ OmniRoute now automatically refreshes model lists for connected providers every
|
||||
- **#527** — Claude Code + Codex superpowers loop: `tool_result` blocks now converted to text instead of dropped
|
||||
- **#532** — OpenCode GO API key validation now uses the correct `zen/v1` endpoint (`testKeyBaseUrl`)
|
||||
- **#489** — Antigravity: missing `googleProjectId` returns structured 422 error with reconnect guidance
|
||||
- **#510** — Windows: MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\\Program Files\\...`
|
||||
- **#510** — Windows: MSYS2/Git-Bash paths (`/c/Program Files/...`) are now normalized to `C:\Program Files\...`
|
||||
- **#492** — `omniroute` CLI now detects `mise`/`nvm` when `app/server.js` is missing and shows targeted fix
|
||||
|
||||
### 📖 Documentation
|
||||
@@ -1392,7 +1573,9 @@ OmniRoute now automatically refreshes model lists for connected providers every
|
||||
|
||||
- **CLI tools save masked API key to config files** — `claude-settings`, `cline-settings`, and `openclaw-settings` POST routes now accept a `keyId` param and resolve the real API key from DB before writing to disk. `ClaudeToolCard` updated to send `keyId` instead of the masked display string. Fixes #523, #526.
|
||||
- **Custom embedding providers: `No credentials` error** — `/v1/embeddings` now tracks `credentialsProviderId` separately from the routing prefix, so credentials are fetched from the matching provider node ID rather than the public prefix string. Fixes a regression where `google/gemini-embedding-001` and similar custom-provider models would always fail with a credentials error. Fixes #532-related. (PR #528 by @jacob2826)
|
||||
- **Context cache protection regex misses `\n` prefix** — `CACHE_TAG_PATTERN` in `comboAgentMiddleware.ts` updated to match both literal `\n` (backslash-n) and actual newline U+000A that `combo.ts` streaming injects around the `<omniModel>` tag after fix #515. Fixes #531.
|
||||
- **Context cache protection regex misses `
|
||||
` prefix** — `CACHE_TAG_PATTERN` in `comboAgentMiddleware.ts` updated to match both literal `
|
||||
` (backslash-n) and actual newline U+000A that `combo.ts` streaming injects around the `<omniModel>` tag after fix #515. Fixes #531.
|
||||
|
||||
### ✨ New Providers
|
||||
|
||||
@@ -1412,9 +1595,10 @@ OmniRoute now automatically refreshes model lists for connected providers every
|
||||
— The field is a cache-affinity signal used by Codex; stripping it was preventing prompt cache hits.
|
||||
Fixed in `openai-responses.ts` and `responsesApiHelper.ts`.
|
||||
|
||||
- **fix(combo)**: Escape `\n` in `tagContent` so injected JSON string is valid (#515)
|
||||
- **fix(combo)**: Escape `
|
||||
` in `tagContent` so injected JSON string is valid (#515)
|
||||
— Template literal newlines (U+000A) are not allowed unescaped inside JSON string values.
|
||||
Replaced with `\\n` literal sequences in `open-sse/services/combo.ts`.
|
||||
Replaced with `\n` literal sequences in `open-sse/services/combo.ts`.
|
||||
|
||||
- **fix(usage)**: Sync expired token status back to DB on live auth failure (#491)
|
||||
— When the Limits & Quotas live check returns 401/403, the connection `testStatus` is now updated
|
||||
@@ -1963,7 +2147,7 @@ OmniRoute now automatically refreshes model lists for connected providers every
|
||||
|
||||
### 🐛 Bug Fixes
|
||||
|
||||
- **fix(ci)**: Remove word "any" from comments in `openai-responses.ts` and `chatCore.ts` that were failing the t11 `\bany\b` budget check (false positive from regex counting comments)
|
||||
- **fix(ci)**: Remove word "any" from comments in `openai-responses.ts` and `chatCore.ts` that were failing the t11 `any` budget check (false positive from regex counting comments)
|
||||
- **fix(chatCore)**: Normalize unsupported content part types before forwarding to providers (#409 — Cursor sends `{type:"file"}` when `.md` files are attached; Copilot and other OpenAI-compat providers reject with "type has to be either 'image_url' or 'text'"; fix converts `file`/`document` blocks to `text` and drops unknown types)
|
||||
|
||||
### 🔧 Workflow
|
||||
|
||||
@@ -133,7 +133,7 @@ npm run test:protocols:e2e
|
||||
# Ecosystem compatibility tests
|
||||
npm run test:ecosystem
|
||||
|
||||
# Coverage (55% min statements/lines/functions; 60% branches)
|
||||
# Coverage (60% min statements/lines/functions/branches)
|
||||
npm run test:coverage
|
||||
npm run coverage:report
|
||||
|
||||
@@ -145,10 +145,22 @@ npm run check
|
||||
Coverage notes:
|
||||
|
||||
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
|
||||
- Pull requests must keep the overall coverage gate at **60% or higher** for statements, lines, functions, and branches
|
||||
- If a PR changes production code in `src/`, `open-sse/`, `electron/`, or `bin/`, it must add or update automated tests in the same PR
|
||||
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
|
||||
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
|
||||
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
|
||||
|
||||
### Pull Request Requirements
|
||||
|
||||
Before opening or merging a PR:
|
||||
|
||||
- Run `npm run test:unit`
|
||||
- Run `npm run test:coverage`
|
||||
- Ensure the coverage gate stays at **60%+** for all metrics
|
||||
- Include the changed or added test files in the PR description when production code changed
|
||||
- Check the SonarQube result on the PR when the project secrets are configured in CI
|
||||
|
||||
Current test status: **122 unit test files** covering:
|
||||
|
||||
- Provider translators and format conversion
|
||||
|
||||
110
README.md
110
README.md
@@ -11,9 +11,28 @@ _Your universal API proxy — one endpoint, 60+ providers, zero downtime. Now wi
|
||||
<div align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
[](https://hub.docker.com/r/diegosouzapw/omniroute)
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
[](https://github.com/diegosouzapw/OmniRoute/stargazers)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/commits/main)
|
||||
[](https://github.com/diegosouzapw)
|
||||
[](https://github.com/diegosouzapw/OmniRoute)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/pulls?q=is%3Apr+is%3Aclosed)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/tags)
|
||||
[](https://github.com/diegosouzapw)
|
||||
[](https://github.com/diegosouzapw?tab=followers)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/network/members)
|
||||
[](https://github.com/diegosouzapw/OmniRoute/watchers)
|
||||
|
||||
[](https://github.com/diegosouzapw/OmniRoute/blob/main/LICENSE)
|
||||
[](https://omniroute.online)
|
||||
[](https://chat.whatsapp.com/JI7cDQ1GyaiDHhVBpLxf8b?mode=gi_t)
|
||||
@@ -26,54 +45,6 @@ _Your universal API proxy — one endpoint, 60+ providers, zero downtime. Now wi
|
||||
|
||||
---
|
||||
|
||||
## Breaking Change: Unified Logging Upgrade
|
||||
|
||||
> [!WARNING]
|
||||
> **This release changes both the on-disk request log layout and the logging environment variables.**
|
||||
>
|
||||
> If you are upgrading an existing instance:
|
||||
>
|
||||
> - Request logs now live in `DATA_DIR/call_logs/YYYY-MM-DD/` as **one JSON artifact per request**.
|
||||
> - The old `DATA_DIR/logs/` session folders and `DATA_DIR/log.txt` summary file are removed.
|
||||
> - On the first startup after upgrading, OmniRoute creates a safety backup at `DATA_DIR/log_archives/*.zip` before removing the deprecated request log layout.
|
||||
> - Legacy logging env vars such as `LOG_TO_FILE`, `LOG_FILE_PATH`, `LOG_MAX_FILE_SIZE`, `LOG_RETENTION_DAYS`, `LOG_LEVEL`, `LOG_FORMAT`, `ENABLE_REQUEST_LOGS`, `CALL_LOGS_MAX`, `CALL_LOG_PAYLOAD_MODE`, and `PROXY_LOG_MAX_ENTRIES` are no longer supported.
|
||||
> - Use the new env model instead:
|
||||
> - `APP_LOG_TO_FILE`
|
||||
> - `APP_LOG_FILE_PATH`
|
||||
> - `APP_LOG_MAX_FILE_SIZE`
|
||||
> - `APP_LOG_RETENTION_DAYS`
|
||||
> - `APP_LOG_MAX_FILES`
|
||||
> - `APP_LOG_LEVEL`
|
||||
> - `APP_LOG_FORMAT`
|
||||
> - `CALL_LOG_RETENTION_DAYS`
|
||||
> - `CALL_LOG_MAX_ENTRIES`
|
||||
>
|
||||
> For release details and upgrade notes, see the [CHANGELOG](CHANGELOG.md).
|
||||
|
||||
---
|
||||
|
||||
## 🆕 What's New
|
||||
|
||||
> **Upgrading from v2.9.5?** — See the [full CHANGELOG](CHANGELOG.md#300--2026-03-22-release-candidate--not-yet-merged-to-main) for all changes.
|
||||
|
||||
| Area | Change |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 🔒 **CodeQL Security** | Fixed 10+ CodeQL alerts: polynomial-redos, insecure-randomness, shell-injection remediation |
|
||||
| ✅ **Route Validation** | All 176 API routes now validated with Zod schemas + `validateBody()` — CI `check:route-validation:t06` passes |
|
||||
| 🐛 **omniModel Tag Leak** | Internal `<omniModel>` tags no longer leak to clients in SSE streaming responses (#585) |
|
||||
| 🔑 **Registered Keys API** | Auto-provision API keys via `POST /api/v1/registered-keys` with per-provider/account quota enforcement, idempotency, SHA-256 storage, and optional GitHub issue reporting |
|
||||
| 🎨 **Provider Icons** | 130+ provider logos via `@lobehub/icons` (SVG) with PNG → generic fallback chain |
|
||||
| 🔄 **Model Auto-Sync** | 24h scheduler and manual UI toggle to sync model lists for built-in and custom OpenAI-compatible providers |
|
||||
| 🌐 **OpenCode Zen/Go** | Two new providers from @kang-heewon via PR #530: free tier + subscription tier via `OpencodeExecutor` |
|
||||
| 🐛 **Gemini CLI OAuth** | Actionable error when `GEMINI_OAUTH_CLIENT_SECRET` is missing in Docker (was cryptic Google error) |
|
||||
| 🐛 **OpenCode config** | `saveOpenCodeConfig()` now correctly writes TOML to `XDG_CONFIG_HOME` |
|
||||
| 🐛 **Pinned model override** | `body.model` correctly set to `pinnedModel` on context-cache protection |
|
||||
| 🐛 **Codex/Claude loop** | `tool_result` blocks now converted to text to stop infinite loops |
|
||||
| 🐛 **Login redirect** | Login no longer freezes after skipping password setup |
|
||||
| 🐛 **Windows paths** | MSYS2/Git-Bash paths (`/c/...`) normalized to `C:\...` automatically |
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ Main Dashboard
|
||||
|
||||
<div align="center">
|
||||
@@ -803,6 +774,36 @@ PORT=20128 DASHBOARD_PORT=20129 omniroute
|
||||
# Dashboard: http://localhost:20129
|
||||
```
|
||||
|
||||
### Long-Running Streaming Timeouts
|
||||
|
||||
For most deployments, you only need:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| ------------------------ | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `REQUEST_TIMEOUT_MS` | `600000` | Shared baseline for upstream fetch, hidden Undici timeouts, TLS fingerprint requests, and API bridge request/proxy timeouts |
|
||||
| `STREAM_IDLE_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Maximum gap between streaming chunks before OmniRoute aborts the SSE stream |
|
||||
|
||||
Backward compatibility is preserved: existing `FETCH_TIMEOUT_MS`, `API_BRIDGE_PROXY_TIMEOUT_MS`, and other per-layer timeout vars still work and override the shared baseline.
|
||||
|
||||
Advanced overrides are available if you need finer control:
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
| ---------------------------------------- | ------------------------------------------ | -------------------------------------------------------------------- |
|
||||
| `FETCH_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` | Total upstream request timeout used by the main fetch abort signal |
|
||||
| `FETCH_HEADERS_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Undici time limit for receiving upstream response headers |
|
||||
| `FETCH_BODY_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Undici time limit between upstream body chunks (`0` disables it) |
|
||||
| `FETCH_CONNECT_TIMEOUT_MS` | `30000` | Undici TCP connect timeout |
|
||||
| `FETCH_KEEPALIVE_TIMEOUT_MS` | `4000` | Undici idle keep-alive socket timeout |
|
||||
| `TLS_CLIENT_TIMEOUT_MS` | inherits `FETCH_TIMEOUT_MS` | Timeout for TLS fingerprint requests made through `wreq-js` |
|
||||
| `API_BRIDGE_PROXY_TIMEOUT_MS` | inherits `REQUEST_TIMEOUT_MS` or `30000` | Timeout for `/v1` proxy forwarding from API port to dashboard port |
|
||||
| `API_BRIDGE_SERVER_REQUEST_TIMEOUT_MS` | `max(API_BRIDGE_PROXY_TIMEOUT_MS, 300000)` | Incoming request timeout on the API bridge server |
|
||||
| `API_BRIDGE_SERVER_HEADERS_TIMEOUT_MS` | `60000` | Incoming header timeout on the API bridge server |
|
||||
| `API_BRIDGE_SERVER_KEEPALIVE_TIMEOUT_MS` | `5000` | Keep-alive timeout on the API bridge server |
|
||||
| `API_BRIDGE_SERVER_SOCKET_TIMEOUT_MS` | `0` | Socket inactivity timeout on the API bridge server (`0` disables it) |
|
||||
|
||||
If you run OmniRoute behind Nginx, Caddy, Cloudflare, or another reverse proxy, make sure the proxy
|
||||
timeouts are also higher than your OmniRoute stream/fetch timeouts.
|
||||
|
||||
### 2) Connect providers and create your API key
|
||||
|
||||
1. Open Dashboard → `Providers` and connect at least one provider (OAuth or API key).
|
||||
@@ -1016,7 +1017,9 @@ Dashboard support for Docker deployments now includes a one-click **Cloudflare Q
|
||||
Notes:
|
||||
|
||||
- Quick Tunnel URLs are temporary and change after every restart.
|
||||
- Quick Tunnels are not auto-restored after an OmniRoute or container restart. Re-enable them from the dashboard when needed.
|
||||
- Managed install currently supports Linux, macOS, and Windows on `x64` / `arm64`.
|
||||
- Managed Quick Tunnels default to HTTP/2 transport to avoid noisy QUIC UDP buffer warnings in constrained container environments. Set `CLOUDFLARED_PROTOCOL=quic` or `auto` if you want a different transport.
|
||||
- Docker images bundle system CA roots and pass them to managed `cloudflared`, which avoids TLS trust failures when the tunnel bootstraps inside the container.
|
||||
- SQLite runs in WAL mode. `docker stop` should be allowed to finish so OmniRoute can checkpoint the latest changes back into `storage.sqlite`.
|
||||
- The bundled Compose files already set a 40s stop grace period. If you run the image directly, keep `--stop-timeout 40` (or similar) so manual stops do not cut off shutdown cleanup.
|
||||
@@ -1162,7 +1165,7 @@ Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
|
||||
| `claude-haiku-4.5` | `kr/` | **Unlimited** | No reported daily cap |
|
||||
| `claude-opus-4.6` | `kr/` | **Unlimited** | Latest Opus via Kiro |
|
||||
|
||||
### 🟢 QODER MODELS (Free OAuth — No Credit Card)
|
||||
### 🟢 QODER MODELS (Free PAT via qodercli)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
| ------------------ | ------ | ------------- | --------------- |
|
||||
@@ -1172,6 +1175,9 @@ Cerebras (cerebras/) → Llama/Qwen world-fastest — 1M tok/day
|
||||
| `minimax-m2.1` | `if/` | **Unlimited** | No reported cap |
|
||||
| `kimi-k2` | `if/` | **Unlimited** | No reported cap |
|
||||
|
||||
> Recommended connection method: **Personal Access Token + `qodercli`**. Browser OAuth is
|
||||
> experimental and disabled by default unless `QODER_OAUTH_*` environment variables are configured.
|
||||
|
||||
### 🟡 QWEN MODELS (Device Code Auth)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
@@ -1635,7 +1641,7 @@ Dashboard → Providers → Connect GitHub
|
||||
Models:
|
||||
gh/gpt-5
|
||||
gh/claude-4.5-sonnet
|
||||
gh/gemini-3-pro
|
||||
gh/gemini-3.1-pro-preview
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
203
audit_results.json
Normal file
203
audit_results.json
Normal file
@@ -0,0 +1,203 @@
|
||||
{
|
||||
"auditReportVersion": 2,
|
||||
"vulnerabilities": {
|
||||
"next": {
|
||||
"name": "next",
|
||||
"severity": "high",
|
||||
"isDirect": true,
|
||||
"via": [
|
||||
{
|
||||
"source": 1112592,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js self-hosted applications vulnerable to DoS via Image Optimizer remotePatterns configuration",
|
||||
"url": "https://github.com/advisories/GHSA-9g9p-9gw9-jx7f",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-400", "CWE-770"],
|
||||
"cvss": {
|
||||
"score": 5.9,
|
||||
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"
|
||||
},
|
||||
"range": ">=15.6.0-canary.0 <16.1.5"
|
||||
},
|
||||
{
|
||||
"source": 1112646,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js HTTP request deserialization can lead to DoS when using insecure React Server Components",
|
||||
"url": "https://github.com/advisories/GHSA-h25m-26qc-wcjf",
|
||||
"severity": "high",
|
||||
"cwe": ["CWE-400", "CWE-502"],
|
||||
"cvss": {
|
||||
"score": 7.5,
|
||||
"vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"
|
||||
},
|
||||
"range": ">=16.0.0-beta.0 <16.0.11"
|
||||
},
|
||||
{
|
||||
"source": 1112990,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js has Unbounded Memory Consumption via PPR Resume Endpoint ",
|
||||
"url": "https://github.com/advisories/GHSA-5f7q-jpqc-wp7h",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-400", "CWE-409", "CWE-770"],
|
||||
"cvss": {
|
||||
"score": 5.9,
|
||||
"vectorString": "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H"
|
||||
},
|
||||
"range": ">=16.0.0-beta.0 <16.1.5"
|
||||
},
|
||||
{
|
||||
"source": 1114898,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js: HTTP request smuggling in rewrites",
|
||||
"url": "https://github.com/advisories/GHSA-ggv3-7p47-pfv8",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-444"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=16.0.0-beta.0 <16.1.7"
|
||||
},
|
||||
{
|
||||
"source": 1114941,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js: Unbounded next/image disk cache growth can exhaust storage",
|
||||
"url": "https://github.com/advisories/GHSA-3x4c-7xq6-9pq8",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-400"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=16.0.0-beta.0 <16.1.7"
|
||||
},
|
||||
{
|
||||
"source": 1114942,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js: Unbounded postponed resume buffering can lead to DoS",
|
||||
"url": "https://github.com/advisories/GHSA-h27x-g6w4-24gq",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-770"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=16.0.1 <16.1.7"
|
||||
},
|
||||
{
|
||||
"source": 1114943,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js: null origin can bypass Server Actions CSRF checks",
|
||||
"url": "https://github.com/advisories/GHSA-mq59-m269-xvcx",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-352"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=16.0.1 <16.1.7"
|
||||
},
|
||||
{
|
||||
"source": 1115360,
|
||||
"name": "next",
|
||||
"dependency": "next",
|
||||
"title": "Next.js: null origin can bypass dev HMR websocket CSRF checks",
|
||||
"url": "https://github.com/advisories/GHSA-jcc7-9wpm-mj36",
|
||||
"severity": "low",
|
||||
"cwe": ["CWE-1385"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=16.0.1 <16.1.7"
|
||||
}
|
||||
],
|
||||
"effects": [],
|
||||
"range": "15.6.0-canary.0 - 16.1.6",
|
||||
"nodes": ["node_modules/next"],
|
||||
"fixAvailable": {
|
||||
"name": "next",
|
||||
"version": "16.2.2",
|
||||
"isSemVerMajor": false
|
||||
}
|
||||
},
|
||||
"vite": {
|
||||
"name": "vite",
|
||||
"severity": "high",
|
||||
"isDirect": false,
|
||||
"via": [
|
||||
{
|
||||
"source": 1116007,
|
||||
"name": "vite",
|
||||
"dependency": "vite",
|
||||
"title": "Vite Vulnerable to Path Traversal in Optimized Deps `.map` Handling",
|
||||
"url": "https://github.com/advisories/GHSA-4w7w-66w2-5vf9",
|
||||
"severity": "moderate",
|
||||
"cwe": ["CWE-22", "CWE-200"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=8.0.0 <=8.0.4"
|
||||
},
|
||||
{
|
||||
"source": 1116009,
|
||||
"name": "vite",
|
||||
"dependency": "vite",
|
||||
"title": "Vite: `server.fs.deny` bypassed with queries",
|
||||
"url": "https://github.com/advisories/GHSA-v2wj-q39q-566r",
|
||||
"severity": "high",
|
||||
"cwe": ["CWE-180", "CWE-284"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=8.0.0 <=8.0.4"
|
||||
},
|
||||
{
|
||||
"source": 1116012,
|
||||
"name": "vite",
|
||||
"dependency": "vite",
|
||||
"title": "Vite Vulnerable to Arbitrary File Read via Vite Dev Server WebSocket",
|
||||
"url": "https://github.com/advisories/GHSA-p9ff-h696-f583",
|
||||
"severity": "high",
|
||||
"cwe": ["CWE-200", "CWE-306"],
|
||||
"cvss": {
|
||||
"score": 0,
|
||||
"vectorString": null
|
||||
},
|
||||
"range": ">=8.0.0 <=8.0.4"
|
||||
}
|
||||
],
|
||||
"effects": [],
|
||||
"range": "8.0.0 - 8.0.4",
|
||||
"nodes": ["node_modules/vite"],
|
||||
"fixAvailable": true
|
||||
}
|
||||
},
|
||||
"metadata": {
|
||||
"vulnerabilities": {
|
||||
"info": 0,
|
||||
"low": 0,
|
||||
"moderate": 0,
|
||||
"high": 2,
|
||||
"critical": 0,
|
||||
"total": 2
|
||||
},
|
||||
"dependencies": {
|
||||
"prod": 407,
|
||||
"dev": 485,
|
||||
"optional": 154,
|
||||
"peer": 480,
|
||||
"peerOptional": 0,
|
||||
"total": 1455
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ import { createInterface } from "node:readline";
|
||||
import { resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { existsSync } from "node:fs";
|
||||
import { createHash } from "node:crypto";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const __dirname = dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
@@ -34,8 +34,10 @@ function ask(question) {
|
||||
return new Promise((resolve) => rl.question(question, resolve));
|
||||
}
|
||||
|
||||
function hashPassword(password) {
|
||||
return createHash("sha256").update(password).digest("hex");
|
||||
function generateSecretDigest(input) {
|
||||
// Use bcrypt with a salt round of 10 to match login/route.ts expectations
|
||||
// and resolve CodeQL js/insufficient-password-hash warning.
|
||||
return bcrypt.hashSync(input, 10);
|
||||
}
|
||||
|
||||
console.log("\n🔑 OmniRoute — Password Reset\n");
|
||||
@@ -86,7 +88,7 @@ async function main() {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const hashed = hashPassword(password);
|
||||
const hashed = generateSecretDigest(password);
|
||||
|
||||
// Upsert the password
|
||||
const stmt = db.prepare(`
|
||||
|
||||
23
dbsetup.js
Executable file
23
dbsetup.js
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
import { spawn } from 'node:child_process'
|
||||
|
||||
const env = { ...process.env }
|
||||
|
||||
await exec('npx next build --experimental-build-mode generate')
|
||||
|
||||
// launch application
|
||||
await exec(process.argv.slice(2).join(' '))
|
||||
|
||||
function exec(command) {
|
||||
const child = spawn(command, { shell: true, stdio: 'inherit', env })
|
||||
return new Promise((resolve, reject) => {
|
||||
child.on('exit', code => {
|
||||
if (code === 0) {
|
||||
resolve()
|
||||
} else {
|
||||
reject(new Error(`${command} failed rc=${code}`))
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
17
debug-handles.mjs
Normal file
17
debug-handles.mjs
Normal file
@@ -0,0 +1,17 @@
|
||||
import process from "node:process";
|
||||
import fs from "node:fs";
|
||||
|
||||
setTimeout(() => {
|
||||
const activeHandles = process._getActiveHandles();
|
||||
console.log("ACTIVE HANDLES: " + activeHandles.length);
|
||||
activeHandles.forEach((handle, i) => {
|
||||
console.log(`Handle ${i}:`, handle?.constructor?.name);
|
||||
// if it's a timer or socket, let's see more
|
||||
if (handle?.constructor?.name === "Timeout") {
|
||||
console.log(" Timer wrapper:", handle?._onTimeout?.toString().slice(0, 50));
|
||||
}
|
||||
});
|
||||
process.exit(1);
|
||||
}, 2000);
|
||||
|
||||
await import("./tests/integration/chat-pipeline.test.mjs");
|
||||
14
debug-sockets.mjs
Normal file
14
debug-sockets.mjs
Normal file
@@ -0,0 +1,14 @@
|
||||
import process from "node:process";
|
||||
import("./tests/integration/chat-pipeline.test.mjs").then((mod) => {
|
||||
setTimeout(() => {
|
||||
const activeHandles = process._getActiveHandles();
|
||||
console.log("ACTIVE HANDLES: " + activeHandles.length);
|
||||
activeHandles.forEach((handle, i) => {
|
||||
console.log(`Handle ${i}:`, handle?.constructor?.name);
|
||||
if (handle?.constructor?.name === "Socket") {
|
||||
console.log("Socket ports:", handle?.localPort, handle?.remotePort);
|
||||
}
|
||||
});
|
||||
process.exit(1);
|
||||
}, 15000);
|
||||
});
|
||||
339
debug2.log
Normal file
339
debug2.log
Normal file
@@ -0,0 +1,339 @@
|
||||
TAP version 13
|
||||
# Subtest: Chat Pipeline — handleSingleModelChat decomposition
|
||||
# Subtest: should define resolveModelOrError helper
|
||||
ok 1 - should define resolveModelOrError helper
|
||||
---
|
||||
duration_ms: 2.870676
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should define checkPipelineGates helper
|
||||
ok 2 - should define checkPipelineGates helper
|
||||
---
|
||||
duration_ms: 0.539959
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should define executeChatWithBreaker helper
|
||||
ok 3 - should define executeChatWithBreaker helper
|
||||
---
|
||||
duration_ms: 0.540611
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should keep cost accounting in the core chat pipeline
|
||||
ok 4 - should keep cost accounting in the core chat pipeline
|
||||
---
|
||||
duration_ms: 0.583888
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: handleSingleModelChat should use resolveModelOrError
|
||||
ok 5 - handleSingleModelChat should use resolveModelOrError
|
||||
---
|
||||
duration_ms: 0.395358
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: handleSingleModelChat should use checkPipelineGates
|
||||
ok 6 - handleSingleModelChat should use checkPipelineGates
|
||||
---
|
||||
duration_ms: 0.725771
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: handleSingleModelChat should use executeChatWithBreaker
|
||||
ok 7 - handleSingleModelChat should use executeChatWithBreaker
|
||||
---
|
||||
duration_ms: 0.384009
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: chatCore should record cost for both non-streaming and streaming responses
|
||||
ok 8 - chatCore should record cost for both non-streaming and streaming responses
|
||||
---
|
||||
duration_ms: 0.717301
|
||||
type: 'test'
|
||||
...
|
||||
1..8
|
||||
ok 1 - Chat Pipeline — handleSingleModelChat decomposition
|
||||
---
|
||||
duration_ms: 12.510313
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: Chat Pipeline — combo fallback support
|
||||
# Subtest: should import handleComboChat
|
||||
ok 1 - should import handleComboChat
|
||||
---
|
||||
duration_ms: 0.683569
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should delegate to handleSingleModelChat for each combo model
|
||||
ok 2 - should delegate to handleSingleModelChat for each combo model
|
||||
---
|
||||
duration_ms: 0.903143
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should check model availability before attempting combo models
|
||||
ok 3 - should check model availability before attempting combo models
|
||||
---
|
||||
duration_ms: 0.37494
|
||||
type: 'test'
|
||||
...
|
||||
1..3
|
||||
ok 2 - Chat Pipeline — combo fallback support
|
||||
---
|
||||
duration_ms: 2.526966
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: Chat Pipeline — circuit breaker integration
|
||||
# Subtest: should import CircuitBreakerOpenError
|
||||
ok 1 - should import CircuitBreakerOpenError
|
||||
---
|
||||
duration_ms: 0.500942
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should handle CircuitBreakerOpenError with retry-after
|
||||
ok 2 - should handle CircuitBreakerOpenError with retry-after
|
||||
---
|
||||
duration_ms: 0.262275
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should reject requests when circuit is open
|
||||
ok 3 - should reject requests when circuit is open
|
||||
---
|
||||
duration_ms: 0.399071
|
||||
type: 'test'
|
||||
...
|
||||
1..3
|
||||
ok 3 - Chat Pipeline — circuit breaker integration
|
||||
---
|
||||
duration_ms: 1.532005
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: DI Container — container.ts
|
||||
# Subtest: should export a container singleton
|
||||
ok 1 - should export a container singleton
|
||||
---
|
||||
duration_ms: 293.16418
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should register and resolve a custom service
|
||||
ok 2 - should register and resolve a custom service
|
||||
---
|
||||
duration_ms: 9.047061
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should return cached singleton on repeated resolve
|
||||
ok 3 - should return cached singleton on repeated resolve
|
||||
---
|
||||
duration_ms: 2.700355
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should throw on resolving unregistered service
|
||||
ok 4 - should throw on resolving unregistered service
|
||||
---
|
||||
duration_ms: 3.280776
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should have default registrations
|
||||
ok 5 - should have default registrations
|
||||
---
|
||||
duration_ms: 2.960963
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should support re-registration (overwrite)
|
||||
ok 6 - should support re-registration (overwrite)
|
||||
---
|
||||
duration_ms: 2.683065
|
||||
type: 'test'
|
||||
...
|
||||
1..6
|
||||
ok 4 - DI Container — container.ts
|
||||
---
|
||||
duration_ms: 314.82733
|
||||
type: 'suite'
|
||||
...
|
||||
# [Plugins] Registered "test-logger" (priority: 10, enabled: true)
|
||||
# Subtest: Plugin Architecture — plugins/index.ts
|
||||
# Subtest: should register and list plugins
|
||||
ok 1 - should register and list plugins
|
||||
---
|
||||
duration_ms: 7.470741
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "low" (priority: 200, enabled: true)
|
||||
# [Plugins] Registered "high" (priority: 1, enabled: true)
|
||||
# [Plugins] Registered "mid" (priority: 50, enabled: true)
|
||||
# Subtest: should sort plugins by priority
|
||||
ok 2 - should sort plugins by priority
|
||||
---
|
||||
duration_ms: 3.51882
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "first" (priority: 1, enabled: true)
|
||||
# [Plugins] Registered "second" (priority: 2, enabled: true)
|
||||
# Subtest: should run onRequest hooks in order
|
||||
ok 3 - should run onRequest hooks in order
|
||||
---
|
||||
duration_ms: 2.940782
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "blocker" (priority: 1, enabled: true)
|
||||
# [Plugins] Registered "never-runs" (priority: 2, enabled: true)
|
||||
# [Plugins] Request blocked by "blocker"
|
||||
# Subtest: should support request blocking
|
||||
ok 4 - should support request blocking
|
||||
---
|
||||
duration_ms: 3.293988
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "toggle-me" (priority: 100, enabled: true)
|
||||
# Subtest: should enable/disable plugins at runtime
|
||||
ok 5 - should enable/disable plugins at runtime
|
||||
---
|
||||
duration_ms: 2.784824
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "removable" (priority: 100, enabled: true)
|
||||
# Subtest: should unregister plugins
|
||||
ok 6 - should unregister plugins
|
||||
---
|
||||
duration_ms: 2.608295
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "response-modifier" (priority: 100, enabled: true)
|
||||
# Subtest: should run onResponse hooks
|
||||
ok 7 - should run onResponse hooks
|
||||
---
|
||||
duration_ms: 2.746361
|
||||
type: 'test'
|
||||
...
|
||||
# [Plugins] Registered "error-handler" (priority: 100, enabled: true)
|
||||
# [Plugins] Error recovered by "error-handler"
|
||||
# Subtest: should run onError hooks and allow recovery
|
||||
ok 8 - should run onError hooks and allow recovery
|
||||
---
|
||||
duration_ms: 2.899465
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should return null from onError if no recovery
|
||||
ok 9 - should return null from onError if no recovery
|
||||
---
|
||||
duration_ms: 2.313171
|
||||
type: 'test'
|
||||
...
|
||||
1..9
|
||||
ok 5 - Plugin Architecture — plugins/index.ts
|
||||
---
|
||||
duration_ms: 31.770504
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: Prompt Template Versioning — prompts.ts module existence
|
||||
# Subtest: prompts.ts should exist
|
||||
ok 1 - prompts.ts should exist
|
||||
---
|
||||
duration_ms: 0.369635
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should export CRUD functions
|
||||
ok 2 - should export CRUD functions
|
||||
---
|
||||
duration_ms: 0.391134
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should define PromptTemplate interface
|
||||
ok 3 - should define PromptTemplate interface
|
||||
---
|
||||
duration_ms: 0.333598
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should use content hashing for deduplication
|
||||
ok 4 - should use content hashing for deduplication
|
||||
---
|
||||
duration_ms: 0.31716
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
ok 6 - Prompt Template Versioning — prompts.ts module existence
|
||||
---
|
||||
duration_ms: 1.752975
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: Eval Scheduler — scheduler.ts module existence
|
||||
# Subtest: scheduler.ts should exist
|
||||
ok 1 - scheduler.ts should exist
|
||||
---
|
||||
duration_ms: 0.347059
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should export scheduling functions
|
||||
ok 2 - should export scheduling functions
|
||||
---
|
||||
duration_ms: 0.582836
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should define ScheduledEval and EvalRunResult types
|
||||
ok 3 - should define ScheduledEval and EvalRunResult types
|
||||
---
|
||||
duration_ms: 0.459196
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should have pluggable output provider
|
||||
ok 4 - should have pluggable output provider
|
||||
---
|
||||
duration_ms: 0.310267
|
||||
type: 'test'
|
||||
...
|
||||
1..4
|
||||
ok 7 - Eval Scheduler — scheduler.ts module existence
|
||||
---
|
||||
duration_ms: 1.961338
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: Migration System — files exist
|
||||
# Subtest: migrationRunner.ts should exist
|
||||
ok 1 - migrationRunner.ts should exist
|
||||
---
|
||||
duration_ms: 0.381312
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: 001_initial_schema.sql should exist
|
||||
ok 2 - 001_initial_schema.sql should exist
|
||||
---
|
||||
duration_ms: 0.248336
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: core.ts should reference migration runner
|
||||
ok 3 - core.ts should reference migration runner
|
||||
---
|
||||
duration_ms: 0.542947
|
||||
type: 'test'
|
||||
...
|
||||
1..3
|
||||
ok 8 - Migration System — files exist
|
||||
---
|
||||
duration_ms: 1.448447
|
||||
type: 'suite'
|
||||
...
|
||||
# Subtest: CORS — centralized configuration
|
||||
# Subtest: shared/utils/cors.ts should exist
|
||||
ok 1 - shared/utils/cors.ts should exist
|
||||
---
|
||||
duration_ms: 0.374376
|
||||
type: 'test'
|
||||
...
|
||||
# Subtest: should export CORS_HEADERS and CORS_ORIGIN
|
||||
ok 2 - should export CORS_HEADERS and CORS_ORIGIN
|
||||
---
|
||||
duration_ms: 0.390035
|
||||
type: 'test'
|
||||
...
|
||||
1..2
|
||||
ok 9 - CORS — centralized configuration
|
||||
---
|
||||
duration_ms: 0.962465
|
||||
type: 'suite'
|
||||
...
|
||||
1..9
|
||||
# tests 42
|
||||
# suites 9
|
||||
# pass 42
|
||||
# fail 0
|
||||
# cancelled 0
|
||||
# skipped 0
|
||||
# todo 0
|
||||
# duration_ms 869.387894
|
||||
1772
debug3.log
Normal file
1772
debug3.log
Normal file
File diff suppressed because it is too large
Load Diff
@@ -6,18 +6,20 @@
|
||||
# base → minimal image, no CLI tools
|
||||
# cli → CLIs installed inside the container (portable)
|
||||
# host → runner-base + host-mounted CLI binaries (Linux-first)
|
||||
# cliproxyapi → CLIProxyAPI sidecar on port 8317
|
||||
#
|
||||
# Usage:
|
||||
# docker compose --profile base up -d
|
||||
# docker compose --profile cli up -d
|
||||
# docker compose --profile host up -d
|
||||
# docker compose --profile cliproxyapi up -d
|
||||
# docker compose --profile cli --profile cliproxyapi up -d
|
||||
#
|
||||
# Before first run, copy .env.example → .env and edit your secrets.
|
||||
# ──────────────────────────────────────────────────────────────────────
|
||||
|
||||
x-common: &common
|
||||
restart: unless-stopped
|
||||
stop_grace_period: 40s
|
||||
env_file: .env
|
||||
environment:
|
||||
- DATA_DIR=/app/data # Must match the volume mount below
|
||||
@@ -110,6 +112,30 @@ services:
|
||||
profiles:
|
||||
- host
|
||||
|
||||
# ── Profile: cliproxyapi (CLIProxyAPI as sidecar) ─────────────────
|
||||
cliproxyapi:
|
||||
container_name: cliproxyapi
|
||||
image: ghcr.io/router-for-me/cliproxyapi:v6.9.7
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "${CLIPROXYAPI_PORT:-8317}:${CLIPROXYAPI_PORT:-8317}"
|
||||
volumes:
|
||||
- cliproxyapi-data:/root/.cli-proxy-api
|
||||
environment:
|
||||
- PORT=${CLIPROXYAPI_PORT:-8317}
|
||||
- HOST=0.0.0.0
|
||||
healthcheck:
|
||||
test:
|
||||
["CMD", "wget", "--spider", "-q", "http://127.0.0.1:${CLIPROXYAPI_PORT:-8317}/v1/models"]
|
||||
interval: 30s
|
||||
timeout: 5s
|
||||
retries: 3
|
||||
start_period: 10s
|
||||
profiles:
|
||||
- cliproxyapi
|
||||
|
||||
volumes:
|
||||
omniroute-data:
|
||||
name: omniroute-data
|
||||
cliproxyapi-data:
|
||||
name: cliproxyapi-data
|
||||
|
||||
451
docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
451
docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# OmniRoute Fly.io 部署指南
|
||||
|
||||
本文档记录 OmniRoute 在 Fly.io 上的实际部署方法,适用于两类场景:
|
||||
|
||||
- 首次把当前项目部署到 Fly.io
|
||||
- 后续代码更新后继续发布
|
||||
- 新项目参考同样流程部署
|
||||
|
||||
本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`。
|
||||
|
||||
---
|
||||
|
||||
## 1. 部署目标
|
||||
|
||||
- 平台:Fly.io
|
||||
- 部署方式:本地 `flyctl` 直接发布
|
||||
- 运行方式:使用仓库内现有 `Dockerfile` 和 `fly.toml`
|
||||
- 数据持久化:Fly Volume 挂载到 `/data`
|
||||
- 访问地址:`https://omniroute.fly.dev/`
|
||||
|
||||
---
|
||||
|
||||
## 2. 当前项目关键配置
|
||||
|
||||
当前仓库中的 `fly.toml` 已确认包含以下关键项:
|
||||
|
||||
```toml
|
||||
app = 'omniroute'
|
||||
primary_region = 'sin'
|
||||
|
||||
[[mounts]]
|
||||
source = 'data'
|
||||
destination = '/data'
|
||||
|
||||
[processes]
|
||||
app = 'node run-standalone.mjs'
|
||||
|
||||
[http_service]
|
||||
internal_port = 20128
|
||||
|
||||
[env]
|
||||
TZ = "Asia/Shanghai"
|
||||
HOST = "0.0.0.0"
|
||||
HOSTNAME = "0.0.0.0"
|
||||
BIND = "0.0.0.0"
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `app = 'omniroute'` 决定实际部署到哪个 Fly 应用
|
||||
- `destination = '/data'` 决定持久卷挂载目录
|
||||
- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录
|
||||
|
||||
---
|
||||
|
||||
## 3. 必备工具
|
||||
|
||||
### 3.1 安装 Fly CLI
|
||||
|
||||
Windows PowerShell:
|
||||
|
||||
```powershell
|
||||
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
|
||||
```
|
||||
|
||||
如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。
|
||||
|
||||
### 3.2 登录 Fly 账号
|
||||
|
||||
```powershell
|
||||
flyctl auth login
|
||||
```
|
||||
|
||||
### 3.3 检查登录状态
|
||||
|
||||
```powershell
|
||||
flyctl auth whoami
|
||||
flyctl version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 首次部署当前项目
|
||||
|
||||
### 4.1 获取代码并进入目录
|
||||
|
||||
```powershell
|
||||
git clone https://github.com/xiaoge1688/OmniRoute.git
|
||||
cd OmniRoute
|
||||
```
|
||||
|
||||
### 4.2 确认应用名
|
||||
|
||||
打开 `fly.toml`,重点看这一行:
|
||||
|
||||
```toml
|
||||
app = 'omniroute'
|
||||
```
|
||||
|
||||
如果你准备部署到自己的新应用,可改成全局唯一名称,例如:
|
||||
|
||||
```toml
|
||||
app = 'omniroute-yourname'
|
||||
```
|
||||
|
||||
注意:
|
||||
|
||||
- 控制台里要看的是与 `fly.toml` 里 `app` 一致的应用
|
||||
- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆
|
||||
|
||||
### 4.3 创建应用
|
||||
|
||||
如果该应用尚不存在:
|
||||
|
||||
```powershell
|
||||
flyctl apps create omniroute
|
||||
```
|
||||
|
||||
如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。
|
||||
|
||||
### 4.4 首次部署
|
||||
|
||||
```powershell
|
||||
flyctl deploy
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. 必配参数
|
||||
|
||||
本项目在 Fly.io 上建议至少配置以下参数。
|
||||
|
||||
### 5.1 已验证使用的参数
|
||||
|
||||
这些参数已经在当前 `omniroute` 应用上实际部署:
|
||||
|
||||
- `API_KEY_SECRET`
|
||||
- `DATA_DIR`
|
||||
- `JWT_SECRET`
|
||||
- `MACHINE_ID_SALT`
|
||||
- `NEXT_PUBLIC_BASE_URL`
|
||||
- `STORAGE_ENCRYPTION_KEY`
|
||||
|
||||
### 5.2 关于 `INITIAL_PASSWORD`
|
||||
|
||||
当前项目没有设置 `INITIAL_PASSWORD`,因为本次部署按需求不使用它。
|
||||
|
||||
如果不设置:
|
||||
|
||||
- 启动日志会提示默认密码是 `CHANGEME`
|
||||
- 部署后应尽快在系统设置中修改登录密码
|
||||
|
||||
如果你希望无人值守初始化后台密码,也可以后续补:
|
||||
|
||||
- `INITIAL_PASSWORD`
|
||||
|
||||
---
|
||||
|
||||
## 6. 推荐参数说明
|
||||
|
||||
### 6.1 Secrets 中设置
|
||||
|
||||
建议放入 Fly Secrets:
|
||||
|
||||
| 变量名 | 是否推荐 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| `API_KEY_SECRET` | 必需 | API Key 生成与校验使用 |
|
||||
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
|
||||
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
|
||||
| `MACHINE_ID_SALT` | 推荐 | 生成稳定机器标识 |
|
||||
| `INITIAL_PASSWORD` | 可选 | 首次部署时直接指定后台初始密码 |
|
||||
| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 |
|
||||
|
||||
### 6.2 当前项目推荐值
|
||||
|
||||
| 变量名 | 推荐值 |
|
||||
| --- | --- |
|
||||
| `DATA_DIR` | `/data` |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
|
||||
|
||||
说明:
|
||||
|
||||
- `DATA_DIR=/data` 非常关键,必须与 Fly Volume 挂载点一致
|
||||
- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景
|
||||
|
||||
---
|
||||
|
||||
## 7. 一键设置参数
|
||||
|
||||
下面命令会生成安全随机值,并把当前项目需要的参数一次性写入 Fly Secrets。
|
||||
|
||||
说明:
|
||||
|
||||
- 不包含 `INITIAL_PASSWORD`
|
||||
- 适用于当前项目 `omniroute`
|
||||
|
||||
```powershell
|
||||
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
|
||||
flyctl secrets set `
|
||||
API_KEY_SECRET=$apiKeySecret `
|
||||
JWT_SECRET=$jwtSecret `
|
||||
MACHINE_ID_SALT=$machineIdSalt `
|
||||
STORAGE_ENCRYPTION_KEY=$storageKey `
|
||||
DATA_DIR=/data `
|
||||
NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev `
|
||||
-a omniroute
|
||||
```
|
||||
|
||||
如果你还要加初始密码:
|
||||
|
||||
```powershell
|
||||
flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 查看当前参数
|
||||
|
||||
```powershell
|
||||
flyctl secrets list -a omniroute
|
||||
```
|
||||
|
||||
如果控制台 `Secrets` 页面没有显示你期待的变量,先检查:
|
||||
|
||||
- 看的应用是不是 `omniroute`
|
||||
- `fly.toml` 的 `app` 是否和控制台应用一致
|
||||
|
||||
---
|
||||
|
||||
## 9. 后续更新发布
|
||||
|
||||
代码有更新后,发布步骤很简单:
|
||||
|
||||
```powershell
|
||||
git pull
|
||||
flyctl deploy
|
||||
```
|
||||
|
||||
如果只更新参数,不改代码:
|
||||
|
||||
```powershell
|
||||
flyctl secrets set KEY=value -a omniroute
|
||||
```
|
||||
|
||||
Fly 会自动滚动更新机器。
|
||||
|
||||
### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
|
||||
|
||||
如果当前仓库是 fork,并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新,推荐按下面流程执行。
|
||||
|
||||
先确认远程:
|
||||
|
||||
```powershell
|
||||
git remote -v
|
||||
```
|
||||
|
||||
应至少包含:
|
||||
|
||||
- `origin` 指向你自己的 fork
|
||||
- `upstream` 指向原仓库
|
||||
|
||||
如果没有 `upstream`,先添加:
|
||||
|
||||
```powershell
|
||||
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git
|
||||
```
|
||||
|
||||
同步上游前,先抓取最新提交和标签:
|
||||
|
||||
```powershell
|
||||
git fetch upstream --tags
|
||||
```
|
||||
|
||||
查看当前版本和上游标签:
|
||||
|
||||
```powershell
|
||||
git describe --tags --always
|
||||
git show --no-patch --oneline v3.4.7
|
||||
```
|
||||
|
||||
如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:
|
||||
|
||||
```powershell
|
||||
git merge upstream/main
|
||||
git checkout HEAD~1 -- fly.toml
|
||||
git add -- fly.toml
|
||||
git commit -m "chore(deploy): keep fork fly.toml"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `git merge upstream/main` 用于同步原仓库最新代码
|
||||
- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
|
||||
- 如果上游没有改 `fly.toml`,这一步不会带来额外差异
|
||||
- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 fork 自定义部署配置不被覆盖
|
||||
|
||||
如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否已经包含在 `upstream/main`:
|
||||
|
||||
```powershell
|
||||
git merge-base --is-ancestor v3.4.7 upstream/main
|
||||
```
|
||||
|
||||
返回成功表示 `upstream/main` 已经包含该版本,直接合并 `upstream/main` 即可。
|
||||
|
||||
### 9.2 同步上游后的标准发布顺序
|
||||
|
||||
同步原仓库完成后,推荐按下面顺序发布:
|
||||
|
||||
1. `git fetch upstream --tags`
|
||||
2. `git merge upstream/main`
|
||||
3. 恢复 fork 的 `fly.toml`
|
||||
4. `git push origin main`
|
||||
5. `flyctl deploy`
|
||||
6. `flyctl status -a omniroute`
|
||||
7. `flyctl logs --no-tail -a omniroute`
|
||||
|
||||
这就是当前项目升级到 `v3.4.7` 时使用的实际流程。
|
||||
|
||||
---
|
||||
|
||||
## 10. 发布后检查
|
||||
|
||||
### 10.1 查看应用状态
|
||||
|
||||
```powershell
|
||||
flyctl status -a omniroute
|
||||
```
|
||||
|
||||
### 10.2 查看启动日志
|
||||
|
||||
```powershell
|
||||
flyctl logs --no-tail -a omniroute
|
||||
```
|
||||
|
||||
### 10.3 检查网站可访问
|
||||
|
||||
```powershell
|
||||
try {
|
||||
(Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode
|
||||
} catch {
|
||||
if ($_.Exception.Response) {
|
||||
$_.Exception.Response.StatusCode.value__
|
||||
} else {
|
||||
throw
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
返回 `200` 说明站点已正常响应。
|
||||
|
||||
---
|
||||
|
||||
## 11. 成功标志
|
||||
|
||||
部署成功后,日志里应看到类似内容:
|
||||
|
||||
```text
|
||||
[bootstrap] Secrets persisted to: /data/server.env
|
||||
[DB] SQLite database ready: /data/storage.sqlite
|
||||
```
|
||||
|
||||
这两个点很关键:
|
||||
|
||||
- `/data/server.env` 说明运行时密钥落到了持久卷
|
||||
- `/data/storage.sqlite` 说明数据库写入持久卷
|
||||
|
||||
如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。
|
||||
|
||||
---
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### 12.1 `Secrets` 页面是空的
|
||||
|
||||
通常有两种原因:
|
||||
|
||||
- 你还没执行 `flyctl secrets set`
|
||||
- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`
|
||||
|
||||
### 12.2 `flyctl deploy` 报 `app not found`
|
||||
|
||||
先创建应用:
|
||||
|
||||
```powershell
|
||||
flyctl apps create omniroute
|
||||
```
|
||||
|
||||
### 12.3 `fly.toml` 解析失败
|
||||
|
||||
重点检查:
|
||||
|
||||
- 注释里是否有乱码字符
|
||||
- TOML 引号和缩进是否正确
|
||||
|
||||
### 12.4 数据没有持久化
|
||||
|
||||
检查以下两点:
|
||||
|
||||
- `fly.toml` 中是否存在 `destination = '/data'`
|
||||
- `DATA_DIR` 是否设置为 `/data`
|
||||
|
||||
### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
|
||||
|
||||
可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。
|
||||
|
||||
---
|
||||
|
||||
## 13. 新项目复用建议
|
||||
|
||||
如果以后是新项目照着这份文档部署,最少改这几项:
|
||||
|
||||
1. 修改 `fly.toml` 里的 `app`
|
||||
2. 修改 `NEXT_PUBLIC_BASE_URL`
|
||||
3. 保持 `DATA_DIR=/data`
|
||||
4. 重新生成 `API_KEY_SECRET`、`JWT_SECRET`、`MACHINE_ID_SALT`、`STORAGE_ENCRYPTION_KEY`
|
||||
5. 首次部署后检查日志是否写入 `/data`
|
||||
|
||||
不要直接复用旧项目的密钥。
|
||||
|
||||
---
|
||||
|
||||
## 14. 当前项目的最小发布清单
|
||||
|
||||
当前项目后续最常用的命令如下:
|
||||
|
||||
```powershell
|
||||
flyctl auth whoami
|
||||
flyctl status -a omniroute
|
||||
flyctl secrets list -a omniroute
|
||||
flyctl deploy
|
||||
flyctl logs --no-tail -a omniroute
|
||||
```
|
||||
|
||||
如果只是正常发版,核心就是:
|
||||
|
||||
```powershell
|
||||
flyctl deploy
|
||||
```
|
||||
|
||||
如果是新环境首次部署,核心就是:
|
||||
|
||||
1. `flyctl auth login`
|
||||
2. `flyctl apps create omniroute`
|
||||
3. `flyctl secrets set ... -a omniroute`
|
||||
4. `flyctl deploy`
|
||||
5. `flyctl logs --no-tail -a omniroute`
|
||||
409
docs/I18N.md
Normal file
409
docs/I18N.md
Normal file
@@ -0,0 +1,409 @@
|
||||
# i18n — Internationalization Guide
|
||||
|
||||
OmniRoute supports **30 languages** with full dashboard UI translation, translated documentation, and RTL support for Arabic and Hebrew.
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../I18N.md) | 🇧🇷 [Português (Brasil)](./pt-BR/I18N.md) | 🇪🇸 [Español](./es/I18N.md) | 🇫🇷 [Français](./fr/I18N.md) | 🇩🇪 [Deutsch](./de/I18N.md) | 🇮🇹 [Italiano](./it/I18N.md) | 🇷🇺 [Русский](./ru/I18N.md) | 🇨🇳 [中文 (简体)](./zh-CN/I18N.md) | 🇯🇵 [日本語](./ja/I18N.md) | 🇰🇷 [한국어](./ko/I18N.md) | 🇸🇦 [العربية](./ar/I18N.md) | 🇮🇳 [हिन्दी](./hi/I18N.md) | 🇹🇭 [ไทย](./th/I18N.md) | 🇹🇷 [Türkçe](./tr/I18N.md) | 🇺🇦 [Українська](./uk-UA/I18N.md) | 🇻🇳 [Tiếng Việt](./vi/I18N.md) | 🇧🇬 [Български](./bg/I18N.md) | 🇩🇰 [Dansk](./da/I18N.md) | 🇫🇮 [Suomi](./fi/I18N.md) | 🇮🇱 [עברית](./he/I18N.md) | 🇭🇺 [Magyar](./hu/I18N.md) | 🇮🇩 [Bahasa Indonesia](./id/I18N.md) | 🇲🇾 [Bahasa Melayu](./ms/I18N.md) | 🇳🇱 [Nederlands](./nl/I18N.md) | 🇳🇴 [Norsk](./no/I18N.md) | 🇵🇹 [Português (Portugal)](./pt/I18N.md) | 🇷🇴 [Română](./ro/I18N.md) | 🇵🇱 [Polski](./pl/I18N.md) | 🇸🇰 [Slovenčina](./sk/I18N.md) | 🇸🇪 [Svenska](./sv/I18N.md) | 🇵🇭 [Filipino](./phi/I18N.md) | 🇨🇿 [Čeština](./cs/I18N.md)
|
||||
|
||||
## Quick Reference
|
||||
|
||||
| Task | Command |
|
||||
|------|---------|
|
||||
| Generate translations | `node scripts/i18n/generate-multilang.mjs messages` |
|
||||
| Translate docs (LLM) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model>` |
|
||||
| Validate a locale | `python3 scripts/validate_translation.py quick -l cs` |
|
||||
| Check code keys | `python3 scripts/check_translations.py` |
|
||||
| Generate QA report | `node scripts/i18n/generate-qa-checklist.mjs` |
|
||||
| Visual QA (Playwright) | `node scripts/i18n/run-visual-qa.mjs` |
|
||||
|
||||
## Architecture
|
||||
|
||||
### Source of Truth
|
||||
- **UI strings**: `src/i18n/messages/en.json` (English source, ~2800 keys)
|
||||
- **Locale files**: `src/i18n/messages/{locale}.json` (30 translations)
|
||||
- **Framework**: `next-intl` with cookie-based locale resolution
|
||||
- **Config**: `src/i18n/config.ts` — defines all 30 locales, language names, flags
|
||||
|
||||
### Runtime Flow
|
||||
1. User selects language → `NEXT_LOCALE` cookie set
|
||||
2. `src/i18n/request.ts` resolves locale: cookie → `Accept-Language` header → fallback `en`
|
||||
3. Dynamic import loads `messages/{locale}.json`
|
||||
4. Components use `useTranslations("namespace")` and `t("key")`
|
||||
|
||||
### Supported Locales
|
||||
|
||||
| Code | Language | RTL | Google Translate Code |
|
||||
|------|----------|-----|----------------------|
|
||||
| `ar` | العربية | Yes | `ar` |
|
||||
| `bg` | Български | No | `bg` |
|
||||
| `cs` | Čeština | No | `cs` |
|
||||
| `da` | Dansk | No | `da` |
|
||||
| `de` | Deutsch | No | `de` |
|
||||
| `es` | Español | No | `es` |
|
||||
| `fi` | Suomi | No | `fi` |
|
||||
| `fr` | Français | No | `fr` |
|
||||
| `he` | עברית | Yes | `iw` |
|
||||
| `hi` | हिन्दी | No | `hi` |
|
||||
| `hu` | Magyar | No | `hu` |
|
||||
| `id` | Bahasa Indonesia | No | `id` |
|
||||
| `it` | Italiano | No | `it` |
|
||||
| `ja` | 日本語 | No | `ja` |
|
||||
| `ko` | 한국어 | No | `ko` |
|
||||
| `ms` | Bahasa Melayu | No | `ms` |
|
||||
| `nl` | Nederlands | No | `nl` |
|
||||
| `no` | Norsk | No | `no` |
|
||||
| `phi` | Filipino | No | `tl` |
|
||||
| `pl` | Polski | No | `pl` |
|
||||
| `pt` | Português (Portugal) | No | `pt` |
|
||||
| `pt-BR` | Português (Brasil) | No | `pt` |
|
||||
| `ro` | Română | No | `ro` |
|
||||
| `ru` | Русский | No | `ru` |
|
||||
| `sk` | Slovenčina | No | `sk` |
|
||||
| `sv` | Svenska | No | `sv` |
|
||||
| `th` | ไทย | No | `th` |
|
||||
| `tr` | Türkçe | No | `tr` |
|
||||
| `uk-UA` | Українська | No | `uk` |
|
||||
| `vi` | Tiếng Việt | No | `vi` |
|
||||
| `zh-CN` | 中文 (简体) | No | `zh-CN` |
|
||||
|
||||
## Adding a New Language
|
||||
|
||||
### 1. Register the Locale
|
||||
Edit `src/i18n/config.ts`:
|
||||
```ts
|
||||
// Add to LOCALES array
|
||||
"xx",
|
||||
// Add to LANGUAGES array
|
||||
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
|
||||
```
|
||||
|
||||
### 2. Add to Generator
|
||||
Edit `scripts/i18n/generate-multilang.mjs` — add entry to `LOCALE_SPECS`:
|
||||
```js
|
||||
{
|
||||
code: "xx",
|
||||
googleTl: "xx",
|
||||
label: "XX",
|
||||
flag: "🏳️",
|
||||
languageName: "Language Name",
|
||||
readmeName: "Language Name",
|
||||
docsName: "Language Name",
|
||||
},
|
||||
```
|
||||
|
||||
### 3. Generate Initial Translation
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs messages
|
||||
```
|
||||
This creates `src/i18n/messages/xx.json` auto-translated from `en.json` via Google Translate.
|
||||
|
||||
### 4. Review & Fix Auto-Translations
|
||||
Auto-translations are a starting point. Review manually for:
|
||||
- Technical accuracy
|
||||
- Context-appropriate terminology
|
||||
- Proper handling of placeholders (`{count}`, `{value}`, etc.)
|
||||
|
||||
### 5. Validate
|
||||
```bash
|
||||
python3 scripts/validate_translation.py quick -l xx
|
||||
python3 scripts/validate_translation.py diff common -l xx
|
||||
```
|
||||
|
||||
### 6. Generate Translated Documentation
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs docs
|
||||
```
|
||||
|
||||
## Auto-Translation Pipeline
|
||||
|
||||
### generate-multilang.mjs (Google Translate)
|
||||
|
||||
**Primary auto-translation engine** — uses Google Translate free API to generate translations for UI strings, READMEs, and documentation.
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
|
||||
```
|
||||
|
||||
| Mode | What it does |
|
||||
|------|-------------|
|
||||
| `messages` | Translates missing keys in `src/i18n/messages/{locale}.json` from `en.json` |
|
||||
| `readme` | Translates `README.md` into all locales as `README.{code}.md` in project root |
|
||||
| `docs` | Translates `DOC_SOURCE_FILES` into `docs/i18n/{locale}/{docName}` |
|
||||
| `all` | Runs all three modes |
|
||||
|
||||
**Features:**
|
||||
- **Text protection**: Masks code blocks (```` ``` ````), inline code (`` ` ``), markdown links/images (`[text](url)`), HTML tags, tables, and ICU placeholders (`{count}`, `{value}`, `{total}`, etc.) before translation, then restores them
|
||||
- **Chunked batching**: Joins multiple strings with `__OMNIROUTE_I18N_SEPARATOR__` delimiters to minimize API calls (max 1800 chars per request)
|
||||
- **In-memory cache**: Avoids redundant API calls for repeated strings within a session
|
||||
- **Retry logic**: Exponential backoff (up to 5 attempts with 300ms × attempt delay) for 429/5xx errors
|
||||
- **Timeout**: 20 seconds per request
|
||||
- **Skip existing**: If target file already exists, it is NOT overwritten
|
||||
|
||||
**Important behaviors:**
|
||||
- `docs/i18n/README.md` is **regenerated** each run — it's an auto-generated index of all docs
|
||||
- Root `README.{code}.md` files are only created if they don't exist (skips locales in `EXISTING_README_CODES`)
|
||||
- Language bars (`🌐 **Languages:** ...`) are automatically inserted/updated in all translated docs
|
||||
|
||||
### i18n_autotranslate.py (LLM-based)
|
||||
|
||||
**Secondary translator** — uses any OpenAI-compatible LLM API (including OmniRoute itself) to translate existing `docs/i18n/` markdown files. Best for polishing or re-translating docs with better quality than Google Translate.
|
||||
|
||||
```bash
|
||||
python3 scripts/i18n_autotranslate.py \
|
||||
--api-url http://localhost:20128/v1 \
|
||||
--api-key sk-your-key \
|
||||
--model gpt-4o
|
||||
```
|
||||
|
||||
**Features:**
|
||||
- Scans `docs/i18n/` markdown files for English paragraphs
|
||||
- Skips code blocks, tables, and already-translated content
|
||||
- Sends paragraphs to LLM with technical translation system prompt
|
||||
- Supports all 30 languages
|
||||
|
||||
## Validation & QA
|
||||
|
||||
### validate_translation.py
|
||||
|
||||
**Translation validator** — compares any locale JSON against `en.json` and reports issues.
|
||||
|
||||
```bash
|
||||
# Quick check (counts only)
|
||||
python3 scripts/validate_translation.py quick -l cs
|
||||
# Output:
|
||||
# Missing: 0
|
||||
# Untranslated: 0
|
||||
# Ignored (UNTRANSLATABLE_KEYS): 236
|
||||
|
||||
# Detailed diff by category
|
||||
python3 scripts/validate_translation.py diff common -l cs
|
||||
python3 scripts/validate_translation.py diff settings -l cs
|
||||
|
||||
# Export to CSV
|
||||
python3 scripts/validate_translation.py csv -l cs > report.csv
|
||||
|
||||
# Export to Markdown
|
||||
python3 scripts/validate_translation.py md -l cs > report.md
|
||||
|
||||
# Full report (default)
|
||||
python3 scripts/validate_translation.py -l cs
|
||||
```
|
||||
|
||||
**Detects:**
|
||||
- **Missing keys** — keys in `en.json` but not in locale file
|
||||
- **Extra keys** — keys in locale file but not in `en.json`
|
||||
- **Untranslated keys** — keys where locale value equals English source (excluding allowlist)
|
||||
- **Placeholder mismatches** — ICU placeholders that don't match between source and translation
|
||||
|
||||
**Exit codes:**
|
||||
| Code | Meaning |
|
||||
|------|---------|
|
||||
| 0 | OK |
|
||||
| 1 | Generic error |
|
||||
| 2 | Missing strings (hard error) |
|
||||
| 3 | Untranslated warning (soft) |
|
||||
|
||||
**Environment:** Set `TRANSLATION_LANG=cs` or use `-l cs` flag.
|
||||
|
||||
### check_translations.py
|
||||
|
||||
**Code-to-JSON key checker** — scans `src/**/*.tsx` and `src/**/*.ts` for `useTranslations()` calls and verifies all referenced keys exist in `en.json`.
|
||||
|
||||
```bash
|
||||
# Basic check
|
||||
python3 scripts/check_translations.py
|
||||
|
||||
# Verbose output
|
||||
python3 scripts/check_translations.py --verbose
|
||||
|
||||
# Auto-fix (adds missing keys to en.json)
|
||||
python3 scripts/check_translations.py --fix
|
||||
```
|
||||
|
||||
### generate-qa-checklist.mjs
|
||||
|
||||
**Static analysis QA** — scans Next.js page files for i18n risk metrics and generates a Markdown report.
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-qa-checklist.mjs
|
||||
```
|
||||
|
||||
**Checks:**
|
||||
- Fixed-width class usage (overflow risk)
|
||||
- Directional left/right classes (RTL risk)
|
||||
- Clipping-prone patterns
|
||||
- Locale parity (missing/extra keys vs `en.json`)
|
||||
- README language selector bars in priority locales (`es`, `fr`, `de`, `ja`, `ar`)
|
||||
|
||||
**Output:** `docs/reports/i18n-qa-checklist-{date}.md`
|
||||
|
||||
### run-visual-qa.mjs
|
||||
|
||||
**Visual QA via Playwright** — takes screenshots of all dashboard routes in multiple locales and viewports, then evaluates page health.
|
||||
|
||||
```bash
|
||||
# Default: es, fr, de, ja, ar on localhost:20128
|
||||
node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom base URL and locales
|
||||
QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom routes
|
||||
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
|
||||
```
|
||||
|
||||
**Detects:**
|
||||
- Text overflow
|
||||
- Element clipping
|
||||
- RTL layout mismatches
|
||||
|
||||
**Output:** `docs/reports/i18n-visual-qa-{date}.md` + JSON report
|
||||
|
||||
## Managing Untranslatable Keys
|
||||
|
||||
### untranslatable-keys.json
|
||||
|
||||
**File:** `scripts/i18n/untranslatable-keys.json`
|
||||
|
||||
Allowlist of keys that should remain identical to English source. Used by `validate_translation.py` to avoid false-positive "untranslated" warnings.
|
||||
|
||||
```json
|
||||
{
|
||||
"description": "Keys that should remain untranslated...",
|
||||
"keys": [
|
||||
"common.model",
|
||||
"common.oauth",
|
||||
"health.cpu",
|
||||
...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**What belongs here:**
|
||||
- Brand/product names: `landing.brandName`, `common.social-github`
|
||||
- Technical terms/acronyms: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
|
||||
- ICU/format strings: `apiManager.modelsCount`, `health.millisecondsShort`
|
||||
- Placeholder values: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
|
||||
- Protocol names: `common.http`, `common.oauth`, `providers.oauth2Label`
|
||||
- Navigation sections: `sidebar.primarySection`, `sidebar.cliSection`
|
||||
|
||||
**To add a key:** Edit the `keys` array in `scripts/i18n/untranslatable-keys.json` and re-run validation.
|
||||
|
||||
## CI Integration
|
||||
|
||||
### GitHub Actions (`.github/workflows/ci.yml`)
|
||||
|
||||
The CI pipeline validates all locales on every push and PR:
|
||||
|
||||
1. **`i18n-matrix` job** — dynamically discovers all locale files (excluding `en.json`)
|
||||
2. **`i18n` job** — runs `validate_translation.py quick -l '<lang>'` for each locale in parallel
|
||||
3. **`ci-summary` job** — aggregates results into a dashboard summary
|
||||
|
||||
```yaml
|
||||
# i18n-matrix: discovers languages
|
||||
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
|
||||
|
||||
# i18n: validates each language
|
||||
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
|
||||
```
|
||||
|
||||
**Dashboard output:**
|
||||
```
|
||||
## 🌍 Translations
|
||||
| Metric | Value |
|
||||
|--------|------|
|
||||
| Languages checked | 30 |
|
||||
| Total untranslated | 0 |
|
||||
|
||||
✅ All translations complete
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
src/i18n/
|
||||
├── config.ts # Locale definitions (30 locales, RTL config)
|
||||
├── request.ts # Runtime locale resolution
|
||||
└── messages/
|
||||
├── en.json # Source of truth (~2800 keys)
|
||||
├── cs.json # Czech translation
|
||||
├── de.json # German translation
|
||||
└── ... # 30 locale files total
|
||||
|
||||
scripts/
|
||||
├── i18n/
|
||||
│ ├── generate-multilang.mjs # Auto-translation engine (Google Translate, 888 lines)
|
||||
│ ├── generate-qa-checklist.mjs # Static analysis QA
|
||||
│ ├── run-visual-qa.mjs # Playwright visual QA
|
||||
│ └── untranslatable-keys.json # Allowlist for validation (236 keys)
|
||||
├── validate_translation.py # Translation validator
|
||||
├── check_translations.py # Code-to-JSON key checker
|
||||
└── i18n_autotranslate.py # LLM-based doc translator
|
||||
|
||||
.github/workflows/
|
||||
└── ci.yml # i18n validation in CI matrix
|
||||
|
||||
docs/
|
||||
├── I18N.md # This file — i18n toolchain documentation
|
||||
├── i18n/
|
||||
│ ├── README.md # Auto-generated language index
|
||||
│ ├── cs/ # Czech docs
|
||||
│ │ └── docs/
|
||||
│ │ ├── I18N.md # Czech translation of this file
|
||||
│ │ └── ...
|
||||
│ ├── de/ # German docs
|
||||
│ └── ... # 30 locale directories
|
||||
└── reports/
|
||||
├── i18n-qa-checklist-*.md # Static analysis reports
|
||||
└── i18n-visual-qa-*.md # Visual QA reports
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### When Editing Translations
|
||||
1. **Always edit `en.json` first** — it's the source of truth
|
||||
2. **Run `generate-multilang.mjs messages`** to propagate new keys to all locales
|
||||
3. **Review auto-translations** — Google Translate is a starting point, not final
|
||||
4. **Validate before committing** — `python3 scripts/validate_translation.py quick -l <lang>`
|
||||
5. **Update `untranslatable-keys.json`** if a key should remain in English
|
||||
|
||||
### Placeholder Safety
|
||||
- ICU placeholders (`{count}`, `{value}`, `{total}`, `{seconds}`) must be preserved exactly
|
||||
- Plural formats (`{count, plural, one {# model} other {# models}}`) must maintain structure
|
||||
- The validator detects placeholder mismatches automatically
|
||||
|
||||
### Adding New Translation Keys in Code
|
||||
```tsx
|
||||
// Use namespaced keys
|
||||
const t = useTranslations("settings");
|
||||
t("cacheSettings"); // maps to settings.cacheSettings in JSON
|
||||
|
||||
// Run check_translations.py to verify keys exist
|
||||
python3 scripts/check_translations.py --verbose
|
||||
```
|
||||
|
||||
### RTL Considerations
|
||||
- Arabic (`ar`) and Hebrew (`he`) are RTL locales
|
||||
- Avoid hardcoded `left`/`right` CSS — use `start`/`end` logical properties
|
||||
- Visual QA catches RTL layout mismatches via `run-visual-qa.mjs`
|
||||
|
||||
## Known Issues & History
|
||||
|
||||
### `in.json` → `hi.json` Fix
|
||||
The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This created an orphaned `in.json` duplicate of `hi.json`. Fixed by changing `code: "in"` to `code: "hi"` in `generate-multilang.mjs` and removing the orphaned file.
|
||||
|
||||
### `docs/i18n/README.md` Is Auto-Generated
|
||||
The `docs/i18n/README.md` file is completely regenerated by `generate-multilang.mjs docs`. Any manual edits will be lost. Use `docs/I18N.md` (this file) for hand-written documentation that should persist.
|
||||
|
||||
### External Untranslatable Keys List
|
||||
The `untranslatable-keys.json` allowlist was moved from an inline Python set in `validate_translation.py` to an external JSON file for easier maintenance. The validator loads it at runtime.
|
||||
|
||||
### `generate-multilang.mjs` Hindi Code Fix
|
||||
The generator originally used `code: "in"` (deprecated Google Translate code) for Hindi instead of the correct ISO 639-1 `hi`. This was introduced in upstream commit `952b0b22c` by `diegosouzapw`. Fixed by changing `code: "in"` to `code: "hi"` in the `LOCALE_SPECS` array and removing the orphaned `in.json` file.
|
||||
|
||||
### `validate_translation.py` Ignored Count Output
|
||||
The `quick` check now displays the count of ignored keys from `untranslatable-keys.json`:
|
||||
```
|
||||
Missing: 0
|
||||
Untranslated: 0
|
||||
Ignored (UNTRANSLATABLE_KEYS): 236
|
||||
```
|
||||
@@ -164,7 +164,7 @@ Dashboard → Providers → Connect GitHub
|
||||
Models:
|
||||
gh/gpt-5
|
||||
gh/claude-4.5-sonnet
|
||||
gh/gemini-3-pro
|
||||
gh/gemini-3.1-pro-preview
|
||||
```
|
||||
|
||||
### 💰 Cheap Providers
|
||||
@@ -525,6 +525,7 @@ post_install() {
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
|
||||
| `CLOUDFLARED_BIN` | unset | Use an existing `cloudflared` binary instead of managed download |
|
||||
| `CLOUDFLARED_PROTOCOL` | `http2` | Transport for managed Quick Tunnels (`http2`, `quic`, or `auto`) |
|
||||
| `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 |
|
||||
@@ -652,7 +653,10 @@ Returns models grouped by provider with types (`chat`, `embedding`, `image`).
|
||||
- Available in **Dashboard → Endpoints** for Docker and other self-hosted deployments
|
||||
- Creates a temporary `https://*.trycloudflare.com` URL that forwards to your current OpenAI-compatible `/v1` endpoint
|
||||
- First enable installs `cloudflared` only when needed; later restarts reuse the same managed binary
|
||||
- Quick Tunnels are not auto-restored after an OmniRoute or container restart; re-enable them from the dashboard when needed
|
||||
- Tunnel URLs are ephemeral and change every time you stop/start the tunnel
|
||||
- Managed Quick Tunnels default to HTTP/2 transport to avoid noisy QUIC UDP buffer warnings in constrained containers
|
||||
- Set `CLOUDFLARED_PROTOCOL=quic` or `auto` if you want to override the managed transport choice
|
||||
- Set `CLOUDFLARED_BIN` if you prefer using a preinstalled `cloudflared` binary instead of the managed download
|
||||
|
||||
### LLM Gateway Intelligence (Phase 9)
|
||||
|
||||
@@ -213,8 +213,8 @@ server {
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,6 +228,10 @@ server {
|
||||
NGINX
|
||||
```
|
||||
|
||||
Keep reverse-proxy stream timeouts aligned with your OmniRoute timeout env vars. If you raise
|
||||
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, raise `proxy_read_timeout` / `proxy_send_timeout`
|
||||
above the same threshold.
|
||||
|
||||
### 3.3 Enable and Test
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 🌐 Multilingual Documentation — 9router
|
||||
|
||||
Translations of documentation into 30 languages. Code blocks remain in English.
|
||||
Translations of documentation into 32 languages. Code blocks remain in English.
|
||||
|
||||
---
|
||||
|
||||
@@ -13,7 +13,8 @@ Translations of documentation into 30 languages. Code blocks remain in English.
|
||||
- 🇯🇵 **日本語** (`ja`): [Docs Root](./ja/README.md)
|
||||
- 🇰🇷 **한국어** (`ko`): [Docs Root](./ko/README.md)
|
||||
- 🇸🇦 **العربية** (`ar`): [Docs Root](./ar/README.md)
|
||||
- 🇮🇳 **हिन्दी** (`in`): [Docs Root](./in/README.md)
|
||||
- 🇮🇳 **हिन्दी** (`hi`): [Docs Root](./hi/README.md)
|
||||
- 🇮🇳 **हिन्दी (IN)** (`in`): [Docs Root](./in/README.md)
|
||||
- 🇹🇭 **ไทย** (`th`): [Docs Root](./th/README.md)
|
||||
- 🇻🇳 **Tiếng Việt** (`vi`): [Docs Root](./vi/README.md)
|
||||
- 🇮🇩 **Bahasa Indonesia** (`id`): [Docs Root](./id/README.md)
|
||||
@@ -34,3 +35,4 @@ Translations of documentation into 30 languages. Code blocks remain in English.
|
||||
- 🇵🇭 **Filipino** (`phi`): [Docs Root](./phi/README.md)
|
||||
- 🇧🇷 **Português (Brasil)** (`pt-BR`): [Docs Root](./pt-BR/README.md)
|
||||
- 🇨🇿 **Čeština** (`cs`): [Docs Root](./cs/README.md)
|
||||
- 🇹🇷 **Türkçe** (`tr`): [Docs Root](./tr/README.md)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,64 +1,44 @@
|
||||
# Contributing to OmniRoute (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [hi](../hi/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md) · 🇹🇷 [tr](../tr/CONTRIBUTING.md)
|
||||
|
||||
---
|
||||
|
||||
Thank you for your interest in contributing! This guide covers everything you need to get started.
|
||||
شكرا لاهتمامك بالمساهمة! يغطي هذا الدليل كل ما تحتاجه للبدء.---##إعداد التطوير### Prerequisites
|
||||
|
||||
---
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
|
||||
- **npm** 10+
|
||||
- **Git**
|
||||
|
||||
### Clone & Install
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute
|
||||
npm install
|
||||
```
|
||||
-**Node.js**>= 18 < 24 (موصى به: 22 LTS) -**npm**10+ -**جيت**### النسخ والتثبيت`bash
|
||||
استنساخ بوابة https://github.com/diegosouzapw/OmniRoute.git
|
||||
قرص مضغوط OmniRoute
|
||||
تثبيت npm`
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Create your .env from the template
|
||||
````bash
|
||||
# قم بإنشاء .env الخاص بك من القالب
|
||||
cp .env.example .env
|
||||
|
||||
# Generate required secrets
|
||||
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
|
||||
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
|
||||
```
|
||||
# توليد الأسرار المطلوبة
|
||||
صدى "JWT_SECRET=$(openssl rand -base64 48)" >> .env
|
||||
صدى "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env```
|
||||
|
||||
Key variables for development:
|
||||
المساهمة في التنمية الرئيسية:
|
||||
|
||||
| Variable | Development Default | Description |
|
||||
| فنية | التطوير الافتراضي | الوصف |
|
||||
| ---------------------- | ------------------------ | --------------------- |
|
||||
| `PORT` | `20128` | Server port |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
|
||||
| `JWT_SECRET` | (generate above) | JWT signing secret |
|
||||
| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
|
||||
| `APP_LOG_LEVEL` | `info` | Log verbosity level |
|
||||
| "ميناء" | `20128` | منفذ الخادم |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | عنوان URL الأساسي للواجهة |
|
||||
| `JWT_SECRET` | (أنشئ أعلاه) | سر توقيع JWT |
|
||||
| `INITIAL_PASSWORD` | "التغيير" | كلمة المرور الأولى لتسجيل الدخول |
|
||||
| `APP_LOG_LEVEL` | `معلومات` | تسجيل مستوى الإسهاب |### إعدادات لوحة التحكم
|
||||
|
||||
### Dashboard Settings
|
||||
توفر أدوات تعديل لوحة المعلومات للمستخدم للميزات التي يمكن تهيئتها أيضًا عبر البيئات المتنوعة:
|
||||
|
||||
The dashboard provides UI toggles for features that can also be configured via environment variables:
|
||||
|
||||
| Setting Location | Toggle | Description |
|
||||
| تحديد الموقع | تغيير | الوصف |
|
||||
| ------------------- | ------------------ | ------------------------------ |
|
||||
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
|
||||
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
|
||||
| الإعدادات → متقدمة | وضع الرقعة | أرشيف الطلبات التصحيح (UI) |
|
||||
| الإعدادات → عام | رؤية الشريط الجانبي | إخفاء/ إخفاء أقسام الفصل الجانبي |
|
||||
|
||||
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
|
||||
|
||||
### Running Locally
|
||||
|
||||
```bash
|
||||
يتم تخزين هذه الإعدادات في قاعدة البيانات وتستمر من خلال عمليات إعادة تشغيل التشغيل، مما يؤدي إلى تجاوز إعدادات env var الافتراضية عند ضبطها.### التشغيل محليًا```bash
|
||||
# Development mode (hot reload)
|
||||
npm run dev
|
||||
|
||||
@@ -68,175 +48,156 @@ npm run start
|
||||
|
||||
# Common port configuration
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
```
|
||||
````
|
||||
|
||||
Default URLs:
|
||||
عناوين URL الافتراضية:
|
||||
|
||||
- **Dashboard**: `http://localhost:20128/dashboard`
|
||||
- **API**: `http://localhost:20128/v1`
|
||||
-**لوحة المعلومات**: `http://localhost:20128/dashboard` -**واجهة برمجة التطبيقات**: `http://localhost:20128/v1`---## Git Workflow
|
||||
|
||||
---
|
||||
> ⚠️**لا تلتزم مطلقًا بـ "الرئيسي".**استخدم ميزات الميزات دائمًا.```bash
|
||||
> git checkout -b feat/your-feature-name
|
||||
> #...إجراءات جديدة...
|
||||
> git الالتزام -m "الفذ: وصف التغيير الخاص بك"
|
||||
> git Push -u Origin feat/your-feature-name
|
||||
|
||||
## Git Workflow
|
||||
# قم بتسجيل الطلب على GitHub```### Branch Naming
|
||||
|
||||
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
|
||||
| المبادئ | الحصاد |
|
||||
| --------------- | ------------------------- | ------------------ |
|
||||
| `الفذ/` | مميزات جديدة |
|
||||
| `/` | إصلاحات الشويب |
|
||||
| `إعادة البناء/` | إعادة هيكلة الكود |
|
||||
| `المستندات/` | تأثيرات التوثيق |
|
||||
| `اختبار/` | الإضافات/إصلاحات الاختبار |
|
||||
| `العمل الرتيب/` | الأدوات، CI، التبعيات | ### رسائل الالتزام |
|
||||
|
||||
```bash
|
||||
git checkout -b feat/your-feature-name
|
||||
# ... make changes ...
|
||||
git commit -m "feat: describe your change"
|
||||
git push -u origin feat/your-feature-name
|
||||
# Open a Pull Request on GitHub
|
||||
```
|
||||
اتبع [الالتزامات التقليدية](https://www.conventionalcommits.org/):`
|
||||
الفذ: إضافة قاطع الدائرة لمكالمات المزود
|
||||
الإصلاح: حل حالة حافة التحقق السري من JWT
|
||||
المستندات: قم بتحديث SECURITY.md مع حماية معلومات تحديد الهوية الشخصية (PII).
|
||||
الاختبار: إضافة اختبارات وحدة الملاحظة
|
||||
refactor(db): توحيد جداول حدود المعدل`
|
||||
|
||||
### Branch Naming
|
||||
النطاقات: `db`، `sse`، `oauth`، `dashboard`، `api`، `cli`، `docker`، `ci`، `mcp`، `a2a`، `memory`، `skills`.---## Running Tests
|
||||
|
||||
| Prefix | Purpose |
|
||||
| ----------- | ------------------------- |
|
||||
| `feat/` | New features |
|
||||
| `fix/` | Bug fixes |
|
||||
| `refactor/` | Code restructuring |
|
||||
| `docs/` | Documentation changes |
|
||||
| `test/` | Test additions/fixes |
|
||||
| `chore/` | Tooling, CI, dependencies |
|
||||
````bash
|
||||
# جميع الاختبارات (الوحدة + فيتيست + النظام البيئي + e2e)
|
||||
اختبار تشغيل npm: الكل
|
||||
|
||||
### Commit Messages
|
||||
# ملف اختبار فردي (مشغل الاختبار الأصلي لـ Node.js — تستخدمه معظم الاختبارات)
|
||||
العقدة - استيراد tsx/esm - اختبارات الاختبار/الوحدة/your-file.test.mjs
|
||||
|
||||
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
||||
# Vitest (خادم MCP، autoCombo، ذاكرة التخزين المؤقت)
|
||||
اختبار تشغيل npm: vitest
|
||||
|
||||
```
|
||||
feat: add circuit breaker for provider calls
|
||||
fix: resolve JWT secret validation edge case
|
||||
docs: update SECURITY.md with PII protection
|
||||
test: add observability unit tests
|
||||
refactor(db): consolidate rate limit tables
|
||||
```
|
||||
# اختبارات E2E (يتطلب الكاتب المسرحي)
|
||||
اختبار تشغيل npm: e2e
|
||||
|
||||
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
|
||||
# عملاء البروتوكول E2E (نقل MCP، A2A)
|
||||
اختبار تشغيل npm: البروتوكولات: e2e
|
||||
|
||||
---
|
||||
# اختبارات توافق النظام البيئي
|
||||
اختبار تشغيل npm: النظام البيئي
|
||||
|
||||
## Running Tests
|
||||
# التغطية (60% الحد الأدنى من البيانات/السطور/الوظائف/الفروع)
|
||||
اختبار تشغيل npm: التغطية
|
||||
تغطية تشغيل npm: تقرير
|
||||
|
||||
```bash
|
||||
# All tests (unit + vitest + ecosystem + e2e)
|
||||
npm run test:all
|
||||
# فحص الوبر + التنسيق
|
||||
npm تشغيل الوبر
|
||||
فحص تشغيل npm```
|
||||
|
||||
# Single test file (Node.js native test runner — most tests use this)
|
||||
node --import tsx/esm --test tests/unit/your-file.test.mjs
|
||||
تغطية التعليقات:
|
||||
|
||||
# Vitest (MCP server, autoCombo, cache)
|
||||
npm run test:vitest
|
||||
- `npm run test:coverage` يقيس المصدر لمجموعة اختبار الوحدة الرئيسية، ويستبعد `tests/**`، بما في ذلك `open-sse/**`
|
||||
- يجب أن تحافظ على طلبات التنظيف على بوابة التغطية الشاملة عند**60% أو أعلى**للكشوفات والخطوط والوظائف والأروع
|
||||
- إذا قام ممثل العلاقات العامة تغيير رمز الإنتاج في `src/` أو `open-sse/` أو `electron/` أو `bin/`، فيجب عليه إضافة أو تحديث النقاشة التلقائية في نفس العلاقات العامة
|
||||
- `تغطية تشغيل npm: التقرير' يطبع التقرير التفصيلي لكل ملف على المدى الطويل من أحدث طرق التغطية
|
||||
- `اختبار تشغيل npm:التغطية:التراث` يحافظ على قياس الأقدم للمقارنة التاريخية
|
||||
- راجع`docs/COVERAGE_PLAN.md` للحصول على خارطة طريق تحسين التغطية العامة### سحب متطلبات الطلب
|
||||
|
||||
# E2E tests (requires Playwright)
|
||||
npm run test:e2e
|
||||
قبل فتح أو دمج العلاقات العامة:
|
||||
|
||||
# Protocol clients E2E (MCP transports, A2A)
|
||||
npm run test:protocols:e2e
|
||||
- اختبار تشغيل npm: الوحدة
|
||||
- اختبار تشغيل npm: التغطية
|
||||
- تأكد من بقاء بوابة التغطية عند**60%+**لجميع المعايير
|
||||
- تتضمن ملفات الاختبار التي تم تغييرها أو الهاتفا في وصف العلاقات العامة عند تغيير رمز الإنتاج
|
||||
- التحقق من نتيجة SonarQube على PR عندما يتم التأكد من أسرار المشروع في CI
|
||||
|
||||
# Ecosystem compatibility tests
|
||||
npm run test:ecosystem
|
||||
الاختبار الحالي:**ملفات اختبار 122 وحدة**تغطي:
|
||||
|
||||
# Coverage (55% min statements/lines/functions; 60% branches)
|
||||
npm run test:coverage
|
||||
npm run coverage:report
|
||||
- تحويل المترجمين باستمرار
|
||||
- الحد من المعدل، وقواطع الضوء، والمرونة
|
||||
- ذاكرة تخزين مؤقتة الدلالية، والعجز، وتتبع التقدم
|
||||
- عمليات قاعدة البيانات والمخطط (21 وحدة قاعدة بيانات)
|
||||
- تدفقات OAuth والمصادقة
|
||||
- التحقق من صحة نقطة نهاية واجهة برمجة التطبيقات (Zod v4)
|
||||
- أدوات خادمة MCP وكارثة النطاق
|
||||
- لأنظمة الذاكرة والمهارات---## Code Style
|
||||
|
||||
# Lint + format check
|
||||
npm run lint
|
||||
npm run check
|
||||
```
|
||||
-**ESLint**— يسمح npm run lint قبل الالتزام
|
||||
-**Prettier**— يتم بشكل متزايد من خلال ``التجهيز المرحلي`` عند الالتزام (مسافتان، فواصل منقوطة، علامات رسل مزدوجة، عرض 100 حرف، فاصلة زائدة es5)
|
||||
-**TypeScript**— يستخدم جميع أكواد `src/` `.ts`/`.tsx`؛ `open-sse/` يستخدم `.ts`/`.js`؛ مستند باستخدام TSDoc (`@param`، `@returns`، `@throws`)
|
||||
-**لا يوجد `eval()`**- يفرض ESLint `no-eval`، `no-implied-eval`، `no-new-func`.
|
||||
-**التحقق من صحة Zod**— استخدم مخطط Zod v4 للتأكد من صحة واجهة برمجة التطبيقات (API).
|
||||
-**التسميه**: الملفات = الجمله/علبة الكباب، المكونات = PascalCase، الثوابت = UPPER_SNAKE---## Project Structure
|
||||
|
||||
Coverage notes:
|
||||
````
|
||||
|
||||
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
|
||||
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
|
||||
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
|
||||
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
|
||||
src/ # تايب سكريبت (.ts / .tsx)
|
||||
├── التطبيق/ # Next.js 16 App Router
|
||||
│ ├── (لوحة المعلومات)/ # صفحات لوحة المعلومات (23 قسم)
|
||||
│ ├── واجهة برمجة التطبيقات/ # مسارات واجهة برمجة التطبيقات (51 دليلاً)
|
||||
│ └── تسجيل الدخول/ # صفحات المصادقة (.tsx)
|
||||
├── المجال/ # محرك السياسة (policyEngine، comboResolver، costRules، إلخ.)
|
||||
├── lib/ # منطق العمل الأساسي (.ts)
|
||||
│ ├── a2a/ # خادم بروتوكول وكيل إلى وكيل v0.3
|
||||
│ ├── acp/ # تسجيل بروتوكول اتصال الوكيل
|
||||
│ ├── الامتثال/ # محرك سياسة الامتثال
|
||||
│ ├── db/ # طبقة قاعدة بيانات SQLite (21 وحدة + 16 عملية ترحيل)
|
||||
│ ├── الذاكرة/ # ذاكرة المحادثة المستمرة
|
||||
│ ├── oauth/ # موفرو OAuth والخدمات والأدوات المساعدة
|
||||
│ ├── المهارات/ # إطار المهارات الموسعة
|
||||
│ ├── الاستخدام/ # تتبع الاستخدام وحساب التكلفة
|
||||
│ └── localDb.ts # طبقة إعادة التصدير فقط - لا تقم أبدًا بإضافة المنطق هنا
|
||||
├── البرامج الوسيطة/ # طلب البرامج الوسيطة (promptInjectionGuard)
|
||||
├── mitm/ # وكيل MITM (الشهادة، DNS، التوجيه المستهدف)
|
||||
├── مشترك/
|
||||
│ ├── المكونات/ # مكونات التفاعل (.tsx)
|
||||
│ ├── الثوابت/ # تعريفات الموفر (60+)، نطاقات MCP، استراتيجيات التوجيه
|
||||
│ ├── utils/ # قاطع الدائرة، المطهر، مساعدي المصادقة
|
||||
│ └── التحقق من الصحة/ # مخططات Zod v4
|
||||
└── sse/ # خط أنابيب الوكيل SSE
|
||||
|
||||
Current test status: **122 unit test files** covering:
|
||||
open-sse/ # @omniroute/open-sse Workspace
|
||||
├── المنفذون/ # 14 منفذو الطلبات الخاصة بموفر الخدمة
|
||||
├── المعالجات/ # 11 معالجات الطلب (الدردشة والردود والتضمين والصور وما إلى ذلك)
|
||||
├── mcp-server/ # خادم MCP (25 أداة، 3 عمليات نقل، 10 نطاقات)
|
||||
├── الخدمات/ # 36+ خدمة (combo، autoCombo، RateLimitManager، إلخ.)
|
||||
├── مترجم/ # مترجمو التنسيق (OpenAI ↔ كلود ↔ الجوزاء ↔ الردود ↔ أولاما)
|
||||
├── محول/ # محول API الردود
|
||||
└── utils/ # 22 وحدة مساعدة (الدفق، TLS، الوكيل، التسجيل)
|
||||
|
||||
- Provider translators and format conversion
|
||||
- Rate limiting, circuit breaker, and resilience
|
||||
- Semantic cache, idempotency, progress tracking
|
||||
- Database operations and schema (21 DB modules)
|
||||
- OAuth flows and authentication
|
||||
- API endpoint validation (Zod v4)
|
||||
- MCP server tools and scope enforcement
|
||||
- Memory and Skills systems
|
||||
إلكترون/ # تطبيق إلكترون لسطح المكتب (متعدد المنصات)
|
||||
|
||||
---
|
||||
|
||||
## Code Style
|
||||
|
||||
- **ESLint** — Run `npm run lint` before committing
|
||||
- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
|
||||
- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
|
||||
- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
|
||||
- **Zod validation** — Use Zod v4 schemas for all API input validation
|
||||
- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
src/ # TypeScript (.ts / .tsx)
|
||||
├── app/ # Next.js 16 App Router
|
||||
│ ├── (dashboard)/ # Dashboard pages (23 sections)
|
||||
│ ├── api/ # API routes (51 directories)
|
||||
│ └── login/ # Auth pages (.tsx)
|
||||
├── domain/ # Policy engine (policyEngine, comboResolver, costRules, etc.)
|
||||
├── lib/ # Core business logic (.ts)
|
||||
│ ├── a2a/ # Agent-to-Agent v0.3 protocol server
|
||||
│ ├── acp/ # Agent Communication Protocol registry
|
||||
│ ├── compliance/ # Compliance policy engine
|
||||
│ ├── db/ # SQLite database layer (21 modules + 16 migrations)
|
||||
│ ├── memory/ # Persistent conversational memory
|
||||
│ ├── oauth/ # OAuth providers, services, and utilities
|
||||
│ ├── skills/ # Extensible skill framework
|
||||
│ ├── usage/ # Usage tracking and cost calculation
|
||||
│ └── localDb.ts # Re-export layer only — never add logic here
|
||||
├── middleware/ # Request middleware (promptInjectionGuard)
|
||||
├── mitm/ # MITM proxy (cert, DNS, target routing)
|
||||
├── shared/
|
||||
│ ├── components/ # React components (.tsx)
|
||||
│ ├── constants/ # Provider definitions (60+), MCP scopes, routing strategies
|
||||
│ ├── utils/ # Circuit breaker, sanitizer, auth helpers
|
||||
│ └── validation/ # Zod v4 schemas
|
||||
└── sse/ # SSE proxy pipeline
|
||||
|
||||
open-sse/ # @omniroute/open-sse workspace
|
||||
├── executors/ # 14 provider-specific request executors
|
||||
├── handlers/ # 11 request handlers (chat, responses, embeddings, images, etc.)
|
||||
├── mcp-server/ # MCP server (25 tools, 3 transports, 10 scopes)
|
||||
├── services/ # 36+ services (combo, autoCombo, rateLimitManager, etc.)
|
||||
├── translator/ # Format translators (OpenAI ↔ Claude ↔ Gemini ↔ Responses ↔ Ollama)
|
||||
├── transformer/ # Responses API transformer
|
||||
└── utils/ # 22 utility modules (stream, TLS, proxy, logging)
|
||||
|
||||
electron/ # Electron desktop app (cross-platform)
|
||||
|
||||
tests/
|
||||
├── unit/ # Node.js test runner (122 test files)
|
||||
├── integration/ # Integration tests
|
||||
├── e2e/ # Playwright tests
|
||||
├── security/ # Security tests
|
||||
├── translator/ # Translator-specific tests
|
||||
└── load/ # Load tests
|
||||
|
||||
docs/ # Documentation
|
||||
├── ARCHITECTURE.md # System architecture
|
||||
├── API_REFERENCE.md # All endpoints
|
||||
├── USER_GUIDE.md # Provider setup, CLI integration
|
||||
├── TROUBLESHOOTING.md # Common issues
|
||||
├── MCP-SERVER.md # MCP server (25 tools)
|
||||
├── A2A-SERVER.md # A2A agent protocol
|
||||
├── AUTO-COMBO.md # Auto-combo engine
|
||||
├── CLI-TOOLS.md # CLI tools integration
|
||||
├── COVERAGE_PLAN.md # Test coverage improvement plan
|
||||
├── openapi.yaml # OpenAPI specification
|
||||
└── adr/ # Architecture Decision Records
|
||||
```
|
||||
الاختبارات/
|
||||
├── الوحدة/ # مشغل اختبار Node.js (122 ملف اختبار)
|
||||
├── التكامل/ # اختبارات التكامل
|
||||
├── e2e/ # اختبارات الكاتب المسرحي
|
||||
├── الأمان/ # اختبارات الأمان
|
||||
├── المترجم/ # اختبارات خاصة بالمترجم
|
||||
└── تحميل/ # اختبارات التحميلمستندات/ # التوثيق
|
||||
├── ARCHITECTURE.md # بنية النظام
|
||||
├── API_REFERENCE.md # جميع نقاط النهاية
|
||||
├── USER_GUIDE.md # إعداد الموفر، تكامل CLI
|
||||
├── استكشاف الأخطاء وإصلاحها.md # المشكلات الشائعة
|
||||
├── MCP-SERVER.md # خادم MCP (25 أداة)
|
||||
├── A2A-SERVER.md # بروتوكول الوكيل A2A
|
||||
├── AUTO-COMBO.md # محرك التحرير والسرد التلقائي
|
||||
├── تكامل أدوات CLI-TOOLS.md # تكامل أدوات CLI
|
||||
├── COVERAGE_PLAN.md # اختبار خطة تحسين التغطية
|
||||
├── openapi.yaml # مواصفات OpenAPI
|
||||
└── adr/ # سجلات قرارات الهندسة المعمارية```
|
||||
|
||||
---
|
||||
|
||||
@@ -244,56 +205,31 @@ docs/ # Documentation
|
||||
|
||||
### Step 1: Register Provider Constants
|
||||
|
||||
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
|
||||
أضف إلى `src/shared/constants/providers.ts` - تم التحقق من صحة Zod عند تحميل الوحدة.### الخطوة 2: إضافة Executor (إذا كانت هناك حاجة إلى منطق مخصص)
|
||||
|
||||
### Step 2: Add Executor (if custom logic needed)
|
||||
موجود بالفعل منفذ تنفيذي في open-sse/executors/your-provider.ts لتوسيع المنفذ الأساسي.### الخطوة 3: إضافة مترجم (إذا كان تنسيق غير OpenAI)
|
||||
|
||||
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
|
||||
يجب أن تكون موجودة في الطلب المترجم/الاستجابة في `open-sse/translator/`.### الخطوة 4: إضافة تكوين OAuth (إذا كان يعتمد على OAuth)
|
||||
|
||||
### Step 3: Add Translator (if non-OpenAI format)
|
||||
إضافة بيانات موثوقة OAuth في `src/lib/oauth/constants/oauth.ts` وتطبيقات في `src/lib/oauth/services/`.### الخطوة 5: تسجيل النماذج
|
||||
|
||||
Create request/response translators in `open-sse/translator/`.
|
||||
أضف تعريفات الارتباطات في "open-sse/config/providerRegistry.ts".### الخطوة 6: إضافة الاختبارات
|
||||
|
||||
### Step 4: Add OAuth Config (if OAuth-based)
|
||||
اكتب السيولة الوحدة في `الاختبارات/الوحدة/` التي تغطي الحد الأدنى:
|
||||
|
||||
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
|
||||
- تسجيل المزود
|
||||
- ترجمة الطلب/الرد
|
||||
-تسبب سبب---## Pull Request Checklist
|
||||
|
||||
### Step 5: Register Models
|
||||
- [ ] اجتياز الاختبار (`اختبار npm`)
|
||||
- [ ] طباعات القلم (`npm run lint`)
|
||||
- [ ] نجاح البناء (`npm run build`)
|
||||
- [ ] تمت إضافة أنواع TypeScript للوظائف والواجهات العامة الجديدة
|
||||
- [ ] لا توجد أسرار ضمنية أو قيم بيعة
|
||||
- [ ] تم التحقق من صحة جميع المدخلات باستخدام مخططات Zod
|
||||
- [ ] تم تحديث سجل التغيير (في حالة التغيير الذي يواجهه المستخدم)
|
||||
- [ ] تم تحديث الوثائق (إن وجدت)---## Releasing
|
||||
|
||||
Add model definitions in `open-sse/config/providerRegistry.ts`.
|
||||
تم إدارة الاختلاف عبر سير العمل `/generate-release`. عند إنشاء إصدار GitHub جديد، يتم**نشر المنتج اليدوي إلى npm**عبر إجراءات GitHub.---## Getting Help
|
||||
|
||||
### Step 6: Add Tests
|
||||
|
||||
Write unit tests in `tests/unit/` covering at minimum:
|
||||
|
||||
- Provider registration
|
||||
- Request/response translation
|
||||
- Error handling
|
||||
|
||||
---
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- [ ] Tests pass (`npm test`)
|
||||
- [ ] Linting passes (`npm run lint`)
|
||||
- [ ] Build succeeds (`npm run build`)
|
||||
- [ ] TypeScript types added for new public functions and interfaces
|
||||
- [ ] No hardcoded secrets or fallback values
|
||||
- [ ] All inputs validated with Zod schemas
|
||||
- [ ] CHANGELOG updated (if user-facing change)
|
||||
- [ ] Documentation updated (if applicable)
|
||||
|
||||
---
|
||||
|
||||
## Releasing
|
||||
|
||||
Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
||||
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **ADRs**: See `docs/adr/` for architectural decision records
|
||||
-**الهندسة المعمارية**: تجدد [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**مرجع واجهة برمجة التطبيقات**: راجع [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**المشاكل**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**ADRs**: راجع `docs/adr/`
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,179 +1,141 @@
|
||||
# Security Policy (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [hi](../hi/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md) · 🇹🇷 [tr](../tr/SECURITY.md)
|
||||
|
||||
---
|
||||
|
||||
## Reporting Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability in OmniRoute, please report it responsibly:
|
||||
إذا وجدت ثغرة أمنية في OmniRoute، فيرجى إمدادها بطريقة مختلفة:
|
||||
|
||||
1. **DO NOT** open a public GitHub issue
|
||||
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
|
||||
3. Include: description, reproduction steps, and potential impact
|
||||
1.**لا**تفتح مشكلة عامة على GitHub 2. استخدم [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. تشمل: الوصف، وخطوات الاستنساخ، والأثر للمناسب## Response Timeline
|
||||
|
||||
## Response Timeline
|
||||
| المرحلة | الهدف |
|
||||
| -------------- | ------------------------ | --------- |
|
||||
| شكر وتقدير | 48 ساعة |
|
||||
| الفرز والتقييم | 5 أيام عمل |
|
||||
| الإصدار | التعديل 14 يوم عمل (حرج) | # التغيير |
|
||||
|
||||
| Stage | Target |
|
||||
| ------------------- | --------------------------- |
|
||||
| Acknowledgment | 48 hours |
|
||||
| Triage & Assessment | 5 business days |
|
||||
| Patch Release | 14 business days (critical) |
|
||||
| النسخة | حالة الدعم |
|
||||
| ------- | ------------ | -------------------- |
|
||||
| 3.4.x | ✅ المشتريات |
|
||||
| 3.0.x | ✅ الأمان |
|
||||
| < 3.0.0 | ❌ غير مدعوم | ---## البنية الأمنية |
|
||||
|
||||
## Supported Versions
|
||||
تم تطبيق نموذج OmniRoute متعدد الأمان: `
|
||||
طلب ← CORS ← مصادقة مفتاح API ← منع الاشتراك الرسمي ← معقم الإدخال ← محدد المعدل ← قاطع ← الموفر`### 🔐 Authentication & Authorization
|
||||
|
||||
| Version | Support Status |
|
||||
| ------- | -------------- |
|
||||
| 3.4.x | ✅ Active |
|
||||
| 3.0.x | ✅ Security |
|
||||
| < 3.0.0 | ❌ Unsupported |
|
||||
| غرض | التنفيذ |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------------ | ------------------------- |
|
||||
| **تسجيل الدخول إلى لوحة التحكم** | اعتماد تعتمد على كلمة المرور باستخدام رموز JWT (ملفات تعريف الارتباط HttpOnly) |
|
||||
| **مصادقة مفتاح واجهة برمجة التطبيقات** | مفاتيح موقعة من HMAC مع التحقق من صحة CRC |
|
||||
| **OAuth 2.0 + PKCE** | مصادقة الموفر المنشط (Claude، Codex، Gemini، Cursor، إلخ) |
|
||||
| **تحديث الرمز المميز** | التحديث التلقائي لرمز OAuth قبل انتهاء الصلاحية |
|
||||
| **ملفات تعريف الارتباط التنسيقة** | `AUTH_COOKIE_SECURE=true` لبيئات HTTPS |
|
||||
| **نطاقات MCP** | 10 نطاقات تفصيلية للتحكم في الوصول إلى أداة MCP | ### 🛡️ التشفير عند الراحة |
|
||||
|
||||
---
|
||||
يتم قراءة كافة التفاصيل المخزنة في SQLite باستخدام**AES-256-GCM**مع اشتقاق مفتاح التشفير:
|
||||
|
||||
## Security Architecture
|
||||
- لوحة مفاتيح برمجة التطبيقات، ورموز الوصول، ورموز التحديث، والرموز المعروفة
|
||||
- النسخة البرتغالية: `enc:v1:<iv>:<ciphertext>:<authTag>`
|
||||
- وضع العبور (نص عادي) عندما لا يتم تعيين `STORAGE_ENCRYPTION_KEY````bash
|
||||
|
||||
OmniRoute implements a multi-layered security model:
|
||||
# إنشاء مفتاح التشفير:
|
||||
|
||||
```
|
||||
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
|
||||
```
|
||||
|
||||
### 🔐 Authentication & Authorization
|
||||
|
||||
| Feature | Implementation |
|
||||
| -------------------- | ---------------------------------------------------------- |
|
||||
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
|
||||
| **API Key Auth** | HMAC-signed keys with CRC validation |
|
||||
| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
|
||||
| **Token Refresh** | Automatic OAuth token refresh before expiry |
|
||||
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
|
||||
| **MCP Scopes** | 10 granular scopes for MCP tool access control |
|
||||
|
||||
### 🛡️ Encryption at Rest
|
||||
|
||||
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
|
||||
|
||||
- API keys, access tokens, refresh tokens, and ID tokens
|
||||
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
|
||||
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
|
||||
|
||||
```bash
|
||||
# Generate encryption key:
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
|
||||
|
||||
### 🧠 Prompt Injection Guard
|
||||
|
||||
Middleware that detects and blocks prompt injection attacks in LLM requests:
|
||||
بسبب الوسيطة التي تكتشف وتمنع الهجمات الرابعة في طلبات LLM:
|
||||
|
||||
| Pattern Type | Severity | Example |
|
||||
| ------------------- | -------- | ---------------------------------------------- |
|
||||
| System Override | High | "ignore all previous instructions" |
|
||||
| Role Hijack | High | "you are now DAN, you can do anything" |
|
||||
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
|
||||
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
|
||||
| Instruction Leak | Medium | "show me your system prompt" |
|
||||
| نوع النمط | دان | مثال |
|
||||
| ------------------- | ----- | -------------------------------- |
|
||||
| تجاوز النظام | عالية | " تجاهل كافة التعليمات السابقة" |
|
||||
| اختطاف الدور | عالية | "أنت الآن دان، يمكنك فعل أي شيء" |
|
||||
| لغرض الشفاء | مي | فواصل مشفرة لكسر نطاق السياقة |
|
||||
| دان/الهروب من السجن | عالية | أسباب مطالبة الهروب من السجن |
|
||||
| تسرب التعليمات | مي | "أرني متشوق النظام الخاص بك" |
|
||||
|
||||
Configure via dashboard (Settings → Security) or `.env`:
|
||||
|
||||
```env
|
||||
INPUT_SANITIZER_ENABLED=true
|
||||
INPUT_SANITIZER_MODE=block # warn | block | redact
|
||||
```
|
||||
قم بالتكوين عبر معلومات اللوحة (الإعدادات → الأمان) أو `.env`:`env
|
||||
INPUT_SANITIZER_ENABLED=صحيح
|
||||
INPUT_SANITIZER_MODE=block # تحذير | كتلة | تنقيح`
|
||||
|
||||
### 🔒 PII Redaction
|
||||
|
||||
Automatic detection and optional redaction of personally identifiable information:
|
||||
الكشف التلقائي والتنقيح الاختياري لمعلومات التعريف الشخصية:
|
||||
|
||||
| PII Type | Pattern | Replacement |
|
||||
| ------------- | --------------------- | ------------------ |
|
||||
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
|
||||
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
|
||||
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
|
||||
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
|
||||
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
|
||||
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
|
||||
| نوع معلومات تحديد الهوية الشخصية | نمط | الاستبدال |
|
||||
| ----------------------------------- | --------------------- | ------------------ | ------ |
|
||||
| البريد الإلكتروني | `user@domain.com` | `[EMAIL_REDACTED]` |
|
||||
| CPF (البرازيل) | `123.456.789-00` | `[CPF_REDACTED]` |
|
||||
| CNPJ (البرازيل) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
|
||||
| بطاقة الائتمان | `4111-1111-1111-1111` | `[CC_REDACTED]` |
|
||||
| هاتف | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
|
||||
| الضمان الاجتماعي (الولايات المتحدة) | `123-45-6789` | `[SSN_REDACTED]` | ```env |
|
||||
|
||||
```env
|
||||
PII_REDACTION_ENABLED=true
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### 🌐 Network Security
|
||||
|
||||
| Feature | Description |
|
||||
| | الوصف |
|
||||
| ------------------------ | ---------------------------------------------------------------- |
|
||||
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
|
||||
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
|
||||
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
|
||||
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
|
||||
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
|
||||
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
|
||||
|**كورس**| أصلية قابلة للتكوين (`CORS_ORIGIN` env var، افتراضية `*`) |
|
||||
|**تصفية IP**| نطاقات IP المخصصة لها/القائمة المحظورة في لوحة المعلومات |
|
||||
|**تحديد المعدل**| حدود الحدود لكل الحدود بدقة تلقائية |
|
||||
|**القطيع الغذائي الرعد**| يمنع Mutex + القفل لكل اتصال 502s المتتالية |
|
||||
|**بصمة TLS**| انتحال بصمة TLS الشبيهة بالمتصفح الرئيسي لاكتشاف الروبوتات |
|
||||
|**بصمة سطر مود**| التنسيق/النص لكل موفر لمطابقة التوقيعات CLI الأصلية |### 🔌 متوافقة والتوافر
|
||||
|
||||
### 🔌 Resilience & Availability
|
||||
|
||||
| Feature | Description |
|
||||
| | الوصف |
|
||||
| ----------------------- | ------------------------------------------------------------------ |
|
||||
| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
|
||||
| **Request Idempotency** | 5-second dedup window for duplicate requests |
|
||||
| **Exponential Backoff** | Automatic retry with increasing delays |
|
||||
| **Health Dashboard** | Real-time provider health monitoring |
|
||||
|**قاطع القراءات**| 3 حالات (مغلق → → مفتوح مفتوح) لكل، بسبب SQLite |
|
||||
|**طلب العجز**| نافذة dedup لمدة 5 ثواني للتحميلات المكررة |
|
||||
|**التراجع الأسي**| إعادة المحاولة الجديدة مع زيادة |
|
||||
|**لوحة المعلومات الصحية**| صحة لرعاية خدمة الوقت الحقيقي |### 📋 مراقبة كاملة
|
||||
|
||||
### 📋 Compliance
|
||||
|
||||
| Feature | Description |
|
||||
| | الوصف |
|
||||
| ------------------ | ----------------------------------------------------------- |
|
||||
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
|
||||
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
|
||||
| **Audit Log** | Administrative actions tracked in `audit_log` table |
|
||||
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
|
||||
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
|
||||
|**الاحتفاظ بالسجل**| التنظيف التلقائي بعد `CALL_LOG_RETENTION_DAYS` |
|
||||
|**إلغاء الاشتراك في عدم التسجيل**| تعمل علامة noLog لكل مفتاح API على تسجيل الطلبات |
|
||||
|**سجل التدقيق**| الإجراءات الإدارية التي تم تتبعها في جدول `audit_log` |
|
||||
|**تدقيق MCP**| تسجيل التدقيق التجاري من SQLite لجميع أدوات الاتصال MCP |
|
||||
|**التحقق من صحة زود**| تم التحقق من صحة جميع مدخلات واجهة برمجة التطبيقات (API) باستخدام مخططات Zod v4 عند تحميل الوحدة النموذجية |---## متغيرات البيئة المطلوبة
|
||||
|
||||
---
|
||||
يجب ضبط جميع الاستخدامات قبل إنشاء الضيوف. سوف يفشل العميل بسرعة**إذا كان مفقودًا أو ضعيف.```bash
|
||||
#مطلوب — لن يبدأ بدون ما يلي:
|
||||
JWT_SECRET=$(openssl rand -base64 48) # دقيقة 32 حرفًا
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # دقيقة 16 حرفًا
|
||||
|
||||
## Required Environment Variables
|
||||
#موصى به — يتيح التشفير في حالة عدم النشاط:
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
|
||||
|
||||
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
|
||||
يرفض المعلم تعلمياً القيم والضعيفة مثل `changeme` أو `secret` أو `password`.---## Docker Security
|
||||
|
||||
```bash
|
||||
# REQUIRED — server will not start without these:
|
||||
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
|
||||
|
||||
# RECOMMENDED — enables encryption at rest:
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
|
||||
|
||||
---
|
||||
|
||||
## Docker Security
|
||||
|
||||
- Use non-root user in production
|
||||
- Mount secrets as read-only volumes
|
||||
- Never copy `.env` files into Docker images
|
||||
- Use `.dockerignore` to exclude sensitive files
|
||||
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--read-only \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
- استخدم المستخدم غير جيجا في الإنتاج
|
||||
- منزل جبلار كمجلدات للقراءة فقط
|
||||
- لا تنسى أبدًا بنسخ ملفات `.env` إلى صور Docker
|
||||
- استخدام `.dockerignore` لاستبعاد الملفات الحساسة
|
||||
- اضبط `AUTH_COOKIE_SECURE=true` عندما يكون خلف HTTPS```bash
|
||||
تشغيل عامل الميناء -d \
|
||||
--اسم الطريق الشامل \
|
||||
--إعادة التشغيل ما لم تتوقف \
|
||||
--للقراءة فقط \
|
||||
-ص20128:20128\
|
||||
-v بيانات المسار الشامل:/app/data \
|
||||
-e JWT_SECRET="$(openssl rand -base64 48)" \
|
||||
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
|
||||
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
-e API_KEY_SECRET = "$ (openssl rand -hex 32)" \
|
||||
-e STORAGE_ENCRYPTION_KEY = "$(openssl rand -hex 32)" \
|
||||
diegosouzapw/omniroute:latest```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Run `npm audit` regularly
|
||||
- Keep dependencies updated
|
||||
- The project uses `husky` + `lint-staged` for pre-commit checks
|
||||
- CI pipeline runs ESLint security rules on every push
|
||||
- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)
|
||||
- يسمح له بدقيق npm
|
||||
- حافظ على تحديثات التبعيات
|
||||
- يستخدم المشروع "husky" + "lint-staged" لفحوصات ما قبل التنفيذ
|
||||
- يقوم بخط أنابيب CI يسمح بمتطلبات أمان ESLint في كل خطوة
|
||||
- تم التحقق من صحة ثوابت الموفر عند تحميل الوحدة عبر Zod (`src/shared/validation/providerSchema.ts`)
|
||||
````
|
||||
|
||||
@@ -1,40 +1,26 @@
|
||||
# OmniRoute A2A Server Documentation (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [hi](../../hi/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md) · 🇹🇷 [tr](../../tr/docs/A2A-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
> بروتوكول وكيل إلى وكيل v0.3 — OmniRoute كوكيل توجيه ذكي## Agent Discovery```bash
|
||||
> curl http://localhost:20128/.well-known/agent.json
|
||||
|
||||
## Agent Discovery
|
||||
````
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
إرجاع بطاقة الوكيل التي تصف قدرات OmniRoute ومهاراتها ومتطلبات المصادقة.---## Authentication
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
تتطلب جميع الطلبات `/a2a` مفتاح برمجة التطبيقات عبر رأس `الإعلان`:```
|
||||
التفويض: الحامل YOUR_OMNIROUTE_API_KEY```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
|
||||
---
|
||||
إذا لم يتم تكوين أي مفتاح API على الخادم، فسيتم تجاوز المصادقة.---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
يرسل رسالة إلى المهارة وينتظر الرد الكامل.```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
@@ -48,153 +34,137 @@ curl -X POST http://localhost:20128/a2a \
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**إجابة:**`json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"result": {
|
||||
"task": { "id": "uuid", "state": "completed" },
|
||||
"artifacts": [{ "type": "text", "content": "..." }],
|
||||
"metadata": {
|
||||
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
|
||||
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
|
||||
"resilience_trace": [
|
||||
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
|
||||
],
|
||||
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
|
||||
"المعرف": "1"،
|
||||
"النتيجة": {
|
||||
"المهمة": { "المعرف": "uuid"، "الحالة": "مكتمل" }،
|
||||
"المصنوعات": [{ "النوع": "نص"، "محتوى": "..." }]،
|
||||
"البيانات الوصفية": {
|
||||
"routing_explanation": "سونيتة claude مختارة عبر الموفر \"anthropic\" (زمن الوصول: 1200 مللي ثانية، التكلفة: 0.003 USD)"،
|
||||
"cost_envelope": { "المقدرة": 0.005، "الفعلي": 0.003، "العملة": "USD" }،
|
||||
""resilience_trace": [
|
||||
{ "الحدث": "primary_selected"، "provider": "anthropic"، "timestamp": "..." }
|
||||
]،
|
||||
"policy_verdict": { "مسموح": صحيح، "السبب": "ضمن حدود الميزانية والحصة" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
}`
|
||||
|
||||
### `message/stream` — SSE Streaming
|
||||
|
||||
Same as `message/send` but returns Server-Sent Events for real-time streaming.
|
||||
|
||||
```bash
|
||||
نفس `الرسالة/الإرسال` ولكنها تُرجع الأحداث المرسلة من الخادم للبث في الوقت الفعلي.```bash
|
||||
curl -N -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
|
||||
**SSE Events:**
|
||||
````
|
||||
|
||||
```
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
|
||||
**أحداث SSE:**```
|
||||
البيانات: {"jsonrpc": "2.0"، "method": "message/stream"، "params": {"task": {"id": "..."، "state": "working"}، "chunk": {"type": "text"، "content": "..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
: نبضات القلب 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
|
||||
```
|
||||
البيانات: {"jsonrpc": "2.0"، "method": "message/stream"، "params": {"task": {"id": "..."، "state": "Completed"}، "بيانات التعريف": {...}}}```
|
||||
|
||||
### `tasks/get` — Query Task Status
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
حليقة -X POST http://localhost:20128/a2a \
|
||||
-H "نوع المحتوى: application/json" \
|
||||
-H "التفويض: حامل YOUR_KEY" \
|
||||
-d '{"jsonrpc": "2.0"، "id": "2"، "method": "tasks/get"، "params": {"taskId": "TASK_UUID"}}'```
|
||||
|
||||
### `tasks/cancel` — Cancel a Task
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"3","method":"tasks/cancel","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
حليقة -X POST http://localhost:20128/a2a \
|
||||
-H "نوع المحتوى: application/json" \
|
||||
-H "التفويض: حامل YOUR_KEY" \
|
||||
-d '{"jsonrpc": "2.0"، "id": "3"، "method": "tasks/cancel"، "params": {"taskId": "TASK_UUID"}}'```
|
||||
|
||||
---
|
||||
|
||||
## Available Skills
|
||||
|
||||
| Skill | Description |
|
||||
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. |
|
||||
| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. |
|
||||
|
||||
---
|
||||
| مهارة | الوصف |
|
||||
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `التوجيه الذكي` | تطالب الطرق عبر خط أنابيب OmniRoute الذكي. إرجاع الاستجابة مع شرح التوجيه والتكلفة وتتبع المرونة. |
|
||||
| `إدارة الحصص` | يجيب على استفسارات اللغة الطبيعية حول حصص الموفرين، ويقترح مجموعات مجانية، ويوفر تصنيفات الحصص. |---
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
````
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
تم الإرسال ← العمل ← مكتمل
|
||||
→ فشل
|
||||
→ ألغيت```
|
||||
|
||||
---
|
||||
- تنتهي المهام بعد 5 دقائق (قابلة للتكوين)
|
||||
- حالات الوحدة الطرفية: "مكتمل"، "فشل"، "تم الإلغاء".
|
||||
- سجل الأحداث يتتبع كل انتقال للحالة---
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Meaning |
|
||||
| :----- | :----------------------------- |
|
||||
| -32700 | Parse error (invalid JSON) |
|
||||
| -32600 | Invalid request / Unauthorized |
|
||||
| -32601 | Method or skill not found |
|
||||
| -32602 | Invalid params |
|
||||
| -32603 | Internal error |
|
||||
|
||||
---
|
||||
| الكود | معنى |
|
||||
| :----- | :----------------------------------- | --- |
|
||||
| -32700 | خطأ في التحليل (JSON غير صالح) |
|
||||
| -32600 | طلب غير صالح / غير مصرح به |
|
||||
| -32601 | لم يتم العثور على الطريقة أو المهارة |
|
||||
| -32602 | معلمات غير صالحة |
|
||||
| -32603 | خطأ داخلي | --- |
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
````python
|
||||
طلبات الاستيراد
|
||||
|
||||
resp = requests.post("http://localhost:20128/a2a", json={
|
||||
"jsonrpc": "2.0", "id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
resp = request.post("http://localhost:20128/a2a", json={
|
||||
"jsonrpc": "2.0"، "id": "1"،
|
||||
"الطريقة": "رسالة/إرسال"،
|
||||
"المعلمات": {
|
||||
"المهارة": "التوجيه الذكي"،
|
||||
"messages": [{"role": "user", "content": "Hello"}]
|
||||
}
|
||||
}, headers={"Authorization": "Bearer YOUR_KEY"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
print(result["metadata"]["routing_explanation"])
|
||||
```
|
||||
النتيجة = resp.json () ["النتيجة"]
|
||||
طباعة (نتيجة ["المصنوعات"] [0] ["المحتوى"])
|
||||
طباعة (نتيجة ["بيانات التعريف"] ["routing_explanation"])```
|
||||
|
||||
### TypeScript (fetch)
|
||||
|
||||
```typescript
|
||||
const resp = await fetch("http://localhost:20128/a2a", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer YOUR_KEY",
|
||||
const resp = انتظار الجلب("http://localhost:20128/a2a", {
|
||||
الطريقة: "POST"،
|
||||
رؤوس: {
|
||||
"نوع المحتوى": "application/json"،
|
||||
التفويض: "الحامل YOUR_KEY"،
|
||||
},
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "1",
|
||||
method: "message/send",
|
||||
params: {
|
||||
skill: "smart-routing",
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
الجسم: JSON.stringify({
|
||||
جسونربك: "2.0"،
|
||||
المعرف: "1"،
|
||||
الطريقة: "رسالة/إرسال"،
|
||||
المعلمات: {
|
||||
المهارة: "التوجيه الذكي"،
|
||||
الرسائل: [{ الدور: "المستخدم"، المحتوى: "مرحبًا" }]،
|
||||
},
|
||||
}),
|
||||
});
|
||||
const { result } = await resp.json();
|
||||
console.log(result.metadata.routing_explanation);
|
||||
```
|
||||
const { result } = انتظار resp.json();
|
||||
console.log(result.metadata.routing_explanation);```
|
||||
````
|
||||
|
||||
@@ -1,28 +1,20 @@
|
||||
# API Reference (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [hi](../../hi/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md) · 🇹🇷 [tr](../../tr/docs/API_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
مرجع كامل لجميع نهاية نقاط OmniRoute API.---## Table of Contents
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
|
||||
## Chat Completions
|
||||
- [إكمالات الدردشة](#إكمالات الدردشة)
|
||||
- [التضمينات](#التضمينات)
|
||||
- [ إنشاء الصور ](#image-generation)
|
||||
- [قائمة التطورات](#list-models)
|
||||
- [نقاط نهاية التوافق](#نقاط نهاية التوافق)
|
||||
- [ذاكرة التخزين المؤقتة الدلالية](#ذاكرة التخزين المؤقتة الدلالية)
|
||||
- [لوحة التحكم والإدارة](#dashboard--management)
|
||||
- [معالجة الطلب](#request-processing)
|
||||
- [المصادقة](#المصادقة)---## Chat Completions
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
@@ -40,24 +32,20 @@ Content-Type: application/json
|
||||
|
||||
### Custom Headers
|
||||
|
||||
| Header | Direction | Description |
|
||||
| ------------------------ | --------- | ------------------------------------------------ |
|
||||
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
|
||||
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
|
||||
| `X-Session-Id` | Request | Sticky session key for external session affinity |
|
||||
| `x_session_id` | Request | Underscore variant also accepted (direct HTTP) |
|
||||
| `Idempotency-Key` | Request | Dedup key (5s window) |
|
||||
| `X-Request-Id` | Request | Alternative dedup key |
|
||||
| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) |
|
||||
| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated |
|
||||
| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on |
|
||||
| `X-OmniRoute-Session-Id` | Response | Effective session ID used by OmniRoute |
|
||||
| رأس | | الوصف |
|
||||
| ------------------------ | ---- | -------------------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | طلب | اضبط على "صحيح" لتجاوز ذاكرة التخزين المؤقتة |
|
||||
| `X-OmniRoute-Progress` | طلب | اضبط على "صحيح" لأحداث التقدم |
|
||||
| `معرف الاستماع X` | طلب | مفتاح جلسة لوجه الفعل |
|
||||
| `x_session_id` | طلب | يتم أيضًا قبول التكيف البيئي (HTTP) |
|
||||
| `مفتاح العجز` | طلب | مفتاح Dedup (نافذة 5 ثواني) |
|
||||
| `معرف الطلب X` | طلب | مفتاح إلغاء الحذف الحذف |
|
||||
| `X-OmniRoute-Cache` | الرد | `HIT` أو `MISS` (غير متدفق) |
|
||||
| `X-OmniRoute-Idempotent` | الرد | `صحيح` إذا تم إلغاء التكرار |
|
||||
| `X-OmniRoute-Progress` | الرد | `ممكن تشغيل` في حالة تتبع التقدم |
|
||||
| `معرف جلسة X-OmniRoute` | الرد | الرقم التعريفي الفعال الذي يستخدمه OmniRoute |
|
||||
|
||||
> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
|
||||
|
||||
---
|
||||
|
||||
## Embeddings
|
||||
> لاحظ Nginx: إذا كنت تعتمد على التكييف الهوائي (على سبيل المثال `x_session_id`)، إلا بتمكين `الشرطات الكهربائية_in_headers on;`.---## Embeddings
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
@@ -70,35 +58,31 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
مقدمو خدمة متاحون: Nebius، وOpenAI، وMistral، وTogether AI، وFireworks، وNVIDIA.```bash
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
GET /v1/embeddings
|
||||
```
|
||||
# قائمة بجميع نماذج التضمين
|
||||
|
||||
الحصول على /v1/embeddings```
|
||||
|
||||
---
|
||||
|
||||
## Image Generation
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
````bash
|
||||
ما بعد /v1/صور/أجيال
|
||||
التفويض: حامل مفتاح API الخاص بك
|
||||
نوع المحتوى: application/json
|
||||
|
||||
{
|
||||
"model": "openai/dall-e-3",
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
"نموذج": "openai/dall-e-3"،
|
||||
"prompt": "غروب الشمس الجميل فوق الجبال"،
|
||||
"الحجم": "1024x1024"
|
||||
}```
|
||||
|
||||
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
الموفرون المتاحون: OpenAI (DALL-E)، xAI (Grok Image)، Together AI (FLUX)، Fireworks AI.```bash
|
||||
# List all image models
|
||||
GET /v1/images/generations
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -115,32 +99,26 @@ Authorization: Bearer your-api-key
|
||||
|
||||
## Compatibility Endpoints
|
||||
|
||||
| Method | Path | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Anthropic |
|
||||
| POST | `/v1/responses` | OpenAI Responses |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| GET | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Anthropic |
|
||||
| GET | `/v1beta/models` | Gemini |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
| الطريقة | المسار | التنسيق |
|
||||
| -------- | --------------------------- | --------------------- | -------------------------------- |
|
||||
| مشاركة | `/v1/chat/completions` | أوبن آي |
|
||||
| مشاركة | `/v1/messages` | انثروبى |
|
||||
| مشاركة | `/v1/الردود` | ردود OpenAI |
|
||||
| مشاركة | `/v1/embeddings` | أوبن آي |
|
||||
| مشاركة | `/v1/images/أجيال` | أوبن آي |
|
||||
| احصل على | `/v1/ النماذج` | أوبن آي |
|
||||
| مشاركة | `/v1/messages/count_tokens` | انثروبى |
|
||||
| احصل على | `/v1beta/models` | الجوزاء |
|
||||
| مشاركة | `/v1beta/models/{...path}` | الجوزاء توليد المحتوى |
|
||||
| مشاركة | `/v1/api/chat` | أولاما | ### مسارات الموفر المخصصة```bash |
|
||||
|
||||
### Dedicated Provider Routes
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Semantic Cache
|
||||
تتم إضافة المبادئ الأصلية للمنتج الأصلي في حالة اشتعالها. الاستعلام عن الارتباطات غير المتطابقة "400".---## Semantic Cache
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
@@ -148,24 +126,21 @@ GET /api/cache/stats
|
||||
|
||||
# Clear all caches
|
||||
DELETE /api/cache/stats
|
||||
```
|
||||
````
|
||||
|
||||
Response example:
|
||||
|
||||
```json
|
||||
المثال النموذجي:`json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
"ذاكرة التخزين المؤقت الدلالية": {
|
||||
"حجم الذاكرة": 42،
|
||||
"memoryMaxSize": 500،
|
||||
"حجم ديسيبل": 128،
|
||||
"معدل الإصابة": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
"العجز": {
|
||||
"المفاتيح النشطة": 3،
|
||||
"windows": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
}`
|
||||
|
||||
---
|
||||
|
||||
@@ -173,293 +148,241 @@ Response example:
|
||||
|
||||
### Authentication
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------------- | ------- | --------------------- |
|
||||
| `/api/auth/login` | POST | Login |
|
||||
| `/api/auth/logout` | POST | Logout |
|
||||
| `/api/settings/require-login` | GET/PUT | Toggle login required |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------------- | -------------- | ------------------------ | ----------------------- |
|
||||
| `/api/auth/login` | مشاركة | تسجيل الدخول |
|
||||
| `/api/auth/logout` | مشاركة | تسجيل الخروج |
|
||||
| `/api/settings/require-login` | الحصول على/وضع | تبديل تسجيل الدخول مطلوب | ### Provider Management |
|
||||
|
||||
### Provider Management
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------- | ------------------ | --------------------------- | --------------- |
|
||||
| `/api/providers` | الحصول على/النشر | قائمة / إنشاء مقدمي الخدمات |
|
||||
| `/api/providers/[id]` | الحصول على/وضع/حذف | إدارة مزود |
|
||||
| `/api/providers/[id]/test` | مشاركة | اختبار اتصال الموفر |
|
||||
| `/api/providers/[id]/models` | احصل على | قائمة نماذج المزود |
|
||||
| `/api/providers/validate` | مشاركة | التحقق من صحة تكوين الموفر |
|
||||
| `/api/provider-nodes*` | منوعه | إدارة عقدة الموفر |
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | نماذج مخصصة | ### OAuth Flows |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------------- | --------------- | ------------------------ |
|
||||
| `/api/providers` | GET/POST | List / create providers |
|
||||
| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider |
|
||||
| `/api/providers/[id]/test` | POST | Test provider connection |
|
||||
| `/api/providers/[id]/models` | GET | List provider models |
|
||||
| `/api/providers/validate` | POST | Validate provider config |
|
||||
| `/api/provider-nodes*` | Various | Provider node management |
|
||||
| `/api/provider-models` | GET/POST/DELETE | Custom models |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------------- | ------- | ------------------------ | -------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | متنوع | OAuth الخاص بموفر الخدمة | ### Routing & Config |
|
||||
|
||||
### OAuth Flows
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------- | ---------------- | --------------------------------- | --------------------- |
|
||||
| `/api/models/alias` | الحصول على/النشر | الأسماء المستعارة للنموذج |
|
||||
| `/api/models/catalog` | احصل على | جميع الموديلات حسب المزود + النوع |
|
||||
| `/api/combos*` | متنوع | إدارة التحرير والسرد |
|
||||
| `/api/keys*` | متنوع | إدارة مفاتيح API |
|
||||
| `/api/pricing` | احصل على | التسعير النموذجي | ### Usage & Analytics |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------------- | ------- | ----------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | --------------------- | ------------ |
|
||||
| `/api/usage/history` | احصل على | تاريخ الاستخدام |
|
||||
| `/api/usage/logs` | احصل على | سجلات الاستخدام |
|
||||
| `/api/usage/request-logs` | احصل على | سجلات على مستوى الطلب |
|
||||
| `/api/usage/[connectionId]` | احصل على | الاستخدام لكل اتصال | ### Settings |
|
||||
|
||||
### Routing & Config
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------------- | ---------------------- | ----------------------------------------------- | -------------- |
|
||||
| `/api/settings` | الحصول على/وضع/التصحيح | الإعدادات العامة |
|
||||
| `/api/settings/proxy` | الحصول على/وضع | تكوين وكيل الشبكة |
|
||||
| `/api/settings/proxy/test` | مشاركة | اختبار اتصال الوكيل |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | القائمة المسموح بها/القائمة المحظورة لعناوين IP |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | الميزانية الرمزية المنطقية |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | موجه النظام العالمي | ### Monitoring |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------- | -------- | ----------------------------- |
|
||||
| `/api/models/alias` | GET/POST | Model aliases |
|
||||
| `/api/models/catalog` | GET | All models by provider + type |
|
||||
| `/api/combos*` | Various | Combo management |
|
||||
| `/api/keys*` | Various | API key management |
|
||||
| `/api/pricing` | GET | Model pricing |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------ | -------------- | -------------------------------------------------------------------------------------------------- | -------------------------- |
|
||||
| `/api/sessions` | احصل على | تتبع الجلسة النشطة |
|
||||
| `/api/rate-limits` | احصل على | حدود المعدل لكل حساب |
|
||||
| `/api/monitoring/health` | احصل على | التحقق من الصحة + ملخص الموفر (`catalogCount`، `configuredCount`، `activeCount`، `monitoredCount`) |
|
||||
| `/api/cache/stats` | الحصول على/حذف | إحصائيات ذاكرة التخزين المؤقت / مسح | ### Backup & Export/Import |
|
||||
|
||||
### Usage & Analytics
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | -------------------------------------------------- | -------------- |
|
||||
| `/api/db-backups` | احصل على | قائمة النسخ الاحتياطية المتاحة |
|
||||
| `/api/db-backups` | ضع | إنشاء نسخة احتياطية يدوية |
|
||||
| `/api/db-backups` | مشاركة | استعادة من نسخة احتياطية محددة |
|
||||
| `/api/db-backups/export` | احصل على | تنزيل قاعدة البيانات كملف .sqlite |
|
||||
| `/api/db-backups/import` | مشاركة | قم بتحميل ملف .sqlite لاستبدال قاعدة البيانات |
|
||||
| `/api/db-backups/exportAll` | احصل على | قم بتنزيل النسخة الاحتياطية الكاملة كأرشيف .tar.gz | ### Cloud Sync |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | -------------------- |
|
||||
| `/api/usage/history` | GET | Usage history |
|
||||
| `/api/usage/logs` | GET | Usage logs |
|
||||
| `/api/usage/request-logs` | GET | Request-level logs |
|
||||
| `/api/usage/[connectionId]` | GET | Per-connection usage |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------- | ------- | ------------------------ | ----------- |
|
||||
| `/api/sync/cloud` | متنوع | عمليات المزامنة السحابية |
|
||||
| `/api/sync/initialize` | مشاركة | تهيئة المزامنة |
|
||||
| `/api/cloud/*` | متنوع | إدارة السحابة | ### Tunnels |
|
||||
|
||||
### Settings
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------- | -------- | ------------------------------------------------------------- | ------------- |
|
||||
| `/api/tunnels/cloudflared` | احصل على | اقرأ حالة تثبيت/تشغيل Cloudflare Quick Tunnel للوحة المعلومات |
|
||||
| `/api/tunnels/cloudflared` | مشاركة | تمكين أو تعطيل نفق Cloudflare السريع (`الإجراء=تمكين/تعطيل`) | ### CLI Tools |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------------- | ------------- | ---------------------- |
|
||||
| `/api/settings` | GET/PUT/PATCH | General settings |
|
||||
| `/api/settings/proxy` | GET/PUT | Network proxy config |
|
||||
| `/api/settings/proxy/test` | POST | Test proxy connection |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------------- | -------- | ------------------- |
|
||||
| `/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 العام |
|
||||
|
||||
### Monitoring
|
||||
تتضمن استجابات واجهة سطر الأوامر: `تم التثبيت`، و`القابل للتشغيل`، و`الأمر`، و`commandPath`، و`runtimeMode`، و`السبب`.### ACP Agents
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `/api/sessions` | GET | Active session tracking |
|
||||
| `/api/rate-limits` | GET | Per-account rate limits |
|
||||
| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
|
||||
| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------- | -------- | -------------------------------------------------------------- |
|
||||
| `/api/acp/agents` | احصل على | قم بإدراج جميع الوكلاء المكتشفين (المضمنين + المخصصين) بالحالة |
|
||||
| `/api/acp/agents` | مشاركة | إضافة وكيل مخصص أو تحديث ذاكرة التخزين المؤقت للكشف |
|
||||
| `/api/acp/agents` | حذف | قم بإزالة وكيل مخصص بواسطة معلمة الاستعلام `id` |
|
||||
|
||||
### Backup & Export/Import
|
||||
تتضمن استجابة GET `الوكلاء []` (المعرف، الاسم، الثنائي، الإصدار، المثبت، البروتوكول، isCustom) و`الملخص` (الإجمالي، المثبت، غير موجود، مدمج، مخصص).### Resilience & Rate Limits
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | --------------------------------------- |
|
||||
| `/api/db-backups` | GET | List available backups |
|
||||
| `/api/db-backups` | PUT | Create a manual backup |
|
||||
| `/api/db-backups` | POST | Restore from a specific backup |
|
||||
| `/api/db-backups/export` | GET | Download database as .sqlite file |
|
||||
| `/api/db-backups/import` | POST | Upload .sqlite file to replace database |
|
||||
| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------- | ------------------ | ------------------------------------ | --------- |
|
||||
| `/api/المرونة` | الحصول على/التصحيح | الحصول على/تحديث ملفات تعريف المرونة |
|
||||
| `/api/resilience/reset` | مشاركة | إعادة ضبط قواطع الدائرة |
|
||||
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
|
||||
| `/api/rate-limit` | احصل على | تكوين حد المعدل العالمي | ### Evals |
|
||||
|
||||
### Cloud Sync
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------ | ---------------- | ------------------------------------- | ------------ |
|
||||
| `/api/evals` | الحصول على/النشر | قائمة مجموعات التقييم / تشغيل التقييم | ### Policies |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------- | ------- | --------------------- |
|
||||
| `/api/sync/cloud` | Various | Cloud sync operations |
|
||||
| `/api/sync/initialize` | POST | Initialize sync |
|
||||
| `/api/cloud/*` | Various | Cloud management |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------- | ------------------ | -------------------- | -------------- |
|
||||
| `/api/policies` | الحصول على/نشر/حذف | إدارة سياسات التوجيه | ### Compliance |
|
||||
|
||||
### Tunnels
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | ---------------------------- | ------------------------------ |
|
||||
| `/api/compliance/audit-log` | احصل على | سجل تدقيق الامتثال (آخر رقم) | ### v1beta (Gemini-Compatible) |
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | ----------------------------------------------------------------------- |
|
||||
| `/api/tunnels/cloudflared` | GET | Read Cloudflare Quick Tunnel install/runtime status for the dashboard |
|
||||
| `/api/tunnels/cloudflared` | POST | Enable or disable the Cloudflare Quick Tunnel (`action=enable/disable`) |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------- | -------- | ------------------------------------ |
|
||||
| `/v1beta/models` | احصل على | قائمة النماذج بصيغة الجوزاء |
|
||||
| `/v1beta/models/{...path}` | مشاركة | الجوزاء `توليد المحتوى` نقطة النهاية |
|
||||
|
||||
### CLI Tools
|
||||
تعكس نقاط النهاية هذه تنسيق Gemini API للعملاء الذين يتوقعون توافق Gemini SDK الأصلي.### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------------------- | ------ | ------------------- |
|
||||
| `/api/cli-tools/claude-settings` | GET | Claude CLI status |
|
||||
| `/api/cli-tools/codex-settings` | GET | Codex CLI status |
|
||||
| `/api/cli-tools/droid-settings` | GET | Droid CLI status |
|
||||
| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status |
|
||||
| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime |
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------- | -------- | -------------------------------------------------- |
|
||||
| `/api/init` | احصل على | فحص تهيئة التطبيق (يستخدم عند التشغيل لأول مرة) |
|
||||
| `/api/tags` | احصل على | علامات النماذج المتوافقة مع Ollama (لعملاء Ollama) |
|
||||
| `/api/restart` | مشاركة | تشغيل إعادة تشغيل الخادم الرشيقة |
|
||||
| `/api/shutdown` | مشاركة | تشغيل إيقاف تشغيل الخادم بشكل رشيق |
|
||||
|
||||
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### ACP Agents
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------- | ------ | -------------------------------------------------------- |
|
||||
| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status |
|
||||
| `/api/acp/agents` | POST | Add custom agent or refresh detection cache |
|
||||
| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param |
|
||||
|
||||
GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
|
||||
|
||||
### Resilience & Rate Limits
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------- | --------- | ------------------------------- |
|
||||
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
|
||||
| `/api/resilience/reset` | POST | Reset circuit breakers |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
| `/api/rate-limit` | GET | Global rate limit configuration |
|
||||
|
||||
### Evals
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------ | -------- | --------------------------------- |
|
||||
| `/api/evals` | GET/POST | List eval suites / run evaluation |
|
||||
|
||||
### Policies
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
|
||||
|
||||
### Compliance
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
|
||||
|
||||
### v1beta (Gemini-Compatible)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | --------------------------------- |
|
||||
| `/v1beta/models` | GET | List models in Gemini format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
|
||||
|
||||
These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
|
||||
|
||||
### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | ------ | ---------------------------------------------------- |
|
||||
| `/api/init` | GET | Application initialization check (used on first run) |
|
||||
| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) |
|
||||
| `/api/restart` | POST | Trigger graceful server restart |
|
||||
| `/api/shutdown` | POST | Trigger graceful server shutdown |
|
||||
|
||||
> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
|
||||
|
||||
---
|
||||
> **ملاحظة:**يتم استخدام نقاط النهاية هذه داخليًا بواسطة النظام أو للتوافق مع عميل Ollama. ولا يتم استدعاؤها عادة من قبل المستخدمين النهائيين.---
|
||||
|
||||
## Audio Transcription
|
||||
|
||||
```bash
|
||||
````bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
التفويض: حامل مفتاح API الخاص بك
|
||||
نوع المحتوى: بيانات متعددة الأجزاء/النموذج```
|
||||
|
||||
Transcribe audio files using Deepgram or AssemblyAI.
|
||||
قم بنسخ الملفات الصوتية باستخدام Deepgram أو AssemblyAI.
|
||||
|
||||
**Request:**
|
||||
|
||||
```bash
|
||||
**طلب:**```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"
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**إجابة:**`json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
"text": "مرحبًا، هذا هو المحتوى الصوتي المكتوب.",
|
||||
"مهمة": "نسخ"،
|
||||
"اللغة": "ar"،
|
||||
"المدة": 12.5
|
||||
}`
|
||||
|
||||
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
**مقدمو الخدمة المدعومين:**`deepgram/nova-3`، `assemblyai/best`.
|
||||
|
||||
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
**الصيغ المدعومة:**`mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.---
|
||||
|
||||
## Ollama Compatibility
|
||||
|
||||
For clients that use Ollama's API format:
|
||||
للعملاء الذين يستخدمون تنسيق واجهة برمجة تطبيقات Olma:```bash
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Requests are automatically translated between Ollama and internal formats.
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Telemetry
|
||||
ترجمة الطلبات الأصلية بين التنسيقات التنسيقات الداخلية.---## Telemetry
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**إجابة:**`json
|
||||
{
|
||||
"providers": {
|
||||
"مقدمو الخدمات": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
"github": { "p50": 180، "p95": 620، "p99": 950، "count": 320 }
|
||||
}
|
||||
}
|
||||
```
|
||||
}`
|
||||
|
||||
---
|
||||
|
||||
## Budget
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
GET /api/usage/budget
|
||||
````bash
|
||||
# احصل على حالة الميزانية لجميع مفاتيح API
|
||||
الحصول على /api/usage/budget
|
||||
|
||||
# Set or update a budget
|
||||
# تعيين أو تحديث الميزانية
|
||||
POST /api/usage/budget
|
||||
Content-Type: application/json
|
||||
نوع المحتوى: application/json
|
||||
|
||||
{
|
||||
"keyId": "key-123",
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
"معرف المفتاح": "مفتاح-123"،
|
||||
"الحد": 50.00،
|
||||
"الفترة": "الشهرية"
|
||||
}```
|
||||
|
||||
---
|
||||
|
||||
## Model Availability
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
GET /api/models/availability
|
||||
# احصل على توفر النموذج في الوقت الفعلي عبر جميع مقدمي الخدمة
|
||||
الحصول على /api/models/availability
|
||||
|
||||
# Check availability for a specific model
|
||||
# التحقق من توفر طراز معين
|
||||
POST /api/models/availability
|
||||
Content-Type: application/json
|
||||
نوع المحتوى: application/json
|
||||
|
||||
{
|
||||
"model": "claude-sonnet-4-5-20250929"
|
||||
}
|
||||
```
|
||||
"نموذج": "كلود السوناتة-4-5-20250929"
|
||||
}```
|
||||
|
||||
---
|
||||
|
||||
## Request Processing
|
||||
|
||||
1. Client sends request to `/v1/*`
|
||||
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
|
||||
3. Model is resolved (direct provider/model or alias/combo)
|
||||
4. Credentials selected from local DB with account availability filtering
|
||||
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
|
||||
6. Provider executor sends upstream request
|
||||
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
|
||||
8. Usage/logging recorded
|
||||
9. Fallback applies on errors according to combo rules
|
||||
1. يرسل العميل طلبًا إلى `/v1/*`
|
||||
2. يستدعي معالج المسار "handleChat"، أو "handleEmbedding"، أو "handleAudioTranscription"، أو "handleImageGeneration".
|
||||
3. تم حل النموذج (المزود/النموذج المباشر أو الاسم المستعار/السرد)
|
||||
4. تم تحديد بيانات الاعتماد من قاعدة البيانات المحلية مع تصفية توفر الحساب
|
||||
5. للدردشة: `handleChatCore` - اكتشاف التنسيق، والترجمة، والتحقق من ذاكرة التخزين المؤقت، والتحقق من الكفاءة
|
||||
6. يقوم منفذ الموفر بإرسال طلب المنبع
|
||||
7. تتم ترجمة الاستجابة مرة أخرى إلى تنسيق العميل (الدردشة) أو إعادتها كما هي (التضمينات/الصور/الصوت)
|
||||
8. تم تسجيل الاستخدام/التسجيل
|
||||
9. يتم تطبيق الإجراء الاحتياطي على الأخطاء وفقًا لقواعد التحرير والسرد
|
||||
|
||||
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
مرجع البنية الكاملة: [`ARCHITECTURE.md`](ARCHITECTURE.md)---
|
||||
|
||||
## Authentication
|
||||
|
||||
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
|
||||
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
|
||||
- `requireLogin` toggleable via `/api/settings/require-login`
|
||||
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
|
||||
- تستخدم مسارات لوحة المعلومات (`/dashboard/*`) ملف تعريف الارتباط `auth_token`
|
||||
- يستخدم تسجيل الدخول تجزئة كلمة المرور المحفوظة؛ الرجوع إلى `INITIAL_PASSWORD`
|
||||
- `requireLogin` قابل للتبديل عبر `/api/settings/require-login`
|
||||
- تتطلب المسارات `/v1/*` بشكل اختياري مفتاح Bearer API عندما يكون `REQUIRE_API_KEY=true`
|
||||
````
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,67 +1,55 @@
|
||||
# OmniRoute Auto-Combo Engine (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [hi](../../hi/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md) · 🇹🇷 [tr](../../tr/docs/AUTO-COMBO.md)
|
||||
|
||||
---
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
> نماذج النماذج الذاتية الإدارة مع تسجيل التعديلات التكيفية## How It Works
|
||||
|
||||
## How It Works
|
||||
يقوم محرك التحرير والسرد التلقائي باختيار أفضل/نموذج ديناميكي لكل طلب باستخدام**وظيفة تسجيل مكونة من 6 اختيارات**:
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
| عامل | الوزن | الوصف |
|
||||
| :-------------- | :---- | :------------------------------------- | ------------- |
|
||||
| الحصة | 0.20 | القدرة المتبقية [0..1] |
|
||||
| الصحة | 0.25 | الفاصل: مغلق=1.0، نصف=0.5، مفتوح=0.0 |
|
||||
| تكلفة الاستثمار | 0.20 | التكلفة العكسية (أرخص = الدرجة الأعلى) |
|
||||
| الكمون | 0.15 | الكمون العكسي p95 (أسرع = الأعلى) |
|
||||
| تاسكفيت | 0.10 | نموذج × درجة اللياقة البدنية لنوع مهم |
|
||||
| | 0.10 | متباينة في الوصول إلى زمن/الأخطاء | ## Mode Packs |
|
||||
|
||||
| Factor | Weight | Description |
|
||||
| :--------- | :----- | :---------------------------------------------- |
|
||||
| Quota | 0.20 | Remaining capacity [0..1] |
|
||||
| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
|
||||
| CostInv | 0.20 | Inverse cost (cheaper = higher score) |
|
||||
| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) |
|
||||
| TaskFit | 0.10 | Model × task type fitness score |
|
||||
| Stability | 0.10 | Low variance in latency/errors |
|
||||
| حزمة | التركيز | الوزن الرئيسي |
|
||||
| :----------------------- | :--------- | :------------------ | ---------------- |
|
||||
| 🚀**الشحن السريع** | السرعة | الكمون: 0.35 |
|
||||
| 💰**توفير التكلفة** | اقتصاد | تكلفة التكلفة: 0.40 |
|
||||
| 🎯**الجودة الجديدة** | أفضل نموذج | المهمة فيت: 0.40 |
|
||||
| 📡**غير متصل بالإنترنت** | التوفر | الحصة: 0.40 | ## الشفاء الذاتي |
|
||||
|
||||
## Mode Packs
|
||||
-**الاستبعاد المؤقت**: النتيجة < 0.2 ← تم الاستبعاد لمدة 5 صباحا ( التراجع المتقدم، الأقصى 30 دقيقة) -**التوعية بقاطع الدورة**: مفتوح → مدمر التدمير؛ HALF_OPEN → طلبات التحقيق -**وضع الحادث**: >50% متوقع → ثم الاستكشاف المتوقع -**استرداد فترة التهدئة**: بعد الاختفاء، يكون الطلب الأول من "تحقيق" مع مهلة الأقل## Bandit Exploration
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
يتم توجيه 5% من الطلبات (القابلة للتكوين) إلى موفر خدمات غير آمنة للاستكشاف. معطل في الحادث.## API```bash
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
|
||||
curl -X POST http://localhost:20128/api/combos/auto \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
|
||||
|
||||
# List auto-combos
|
||||
|
||||
curl http://localhost:20128/api/combos/auto
|
||||
|
||||
```
|
||||
|
||||
## Task Fitness
|
||||
|
||||
30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score).
|
||||
تم تسجيل أكثر من 30 نموذجًا عبر 6 أنواع من المهام (`الترميز`، و`المراجعة`، و`التخطيط`، و`التحليل`، و`تصحيح سبب`، و`التوثيق`). محترف أحرف البدل (على سبيل المثال، `*-coder` → درجة ترميز عالية).## Files
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| ملف | الحصاد |
|
||||
| :------------------------------------------- | :------------------------------------ |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
|
||||
| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles |
|
||||
| `src/app/api/combos/auto/route.ts` | REST API |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | وظيفة الهديف وتطبيع التكيف |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | نموذج × مهمة بحث اللياقة البدنية |
|
||||
| `open-sse/services/autoCombo/engine.ts` | الاختيار المنطقي، قطاع الطرق، ميزانية الإنفاق |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | الابعاد، التفاصيل، حالة الحادث |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 ملفات تعريف للوزن |
|
||||
| `src/app/api/combos/auto/route.ts` | ريست API |
|
||||
```
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
# CLI Tools Setup Guide — OmniRoute (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [hi](../../hi/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md) · 🇹🇷 [tr](../../tr/docs/CLI-TOOLS.md)
|
||||
|
||||
---
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
يشرح هذا الدليل كيفية تثبيت وتكوين جميع أدوات CLI البسيطة للذكاء الاصطناعي والمدعم
|
||||
استخدام**OmniRoute**ك واجهة خلفية موحدة، مما يتيح لك إدارة المفاتيح التركية،
|
||||
تتبع التكلفة، وتبديل الارتباطات، والتسجيل عبر كل أداة.---## How It Works
|
||||
|
||||
```
|
||||
Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilot
|
||||
@@ -22,153 +18,131 @@ Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilo
|
||||
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
**الفوائد:**
|
||||
|
||||
- One API key to manage all tools
|
||||
- Cost tracking across all CLIs in the dashboard
|
||||
- Model switching without reconfiguring every tool
|
||||
- Works locally and on remote servers (VPS)
|
||||
- مفتاح API واحد لإبتكار جميع الأدوات
|
||||
- تتبع التكلفة عبر جميع CLIs في لوحة المعلومات
|
||||
- النموذج النموذجي دون إعادة كل أداة
|
||||
- يعمل محليا وعلى الموقع البعيد (VPS)---## Supported Tools (Dashboard Source of Truth)
|
||||
|
||||
---
|
||||
يتم إنشاء بطاقة معلومات اللوحة في `/dashboard/cli-tools` من `src/shared/constants/cliTools.ts`.
|
||||
القائمة الحالية (v3.0.0-rc.16):
|
||||
|
||||
## Supported Tools (Dashboard Source of Truth)
|
||||
| أداة | معرف | الأمر | وضع الإعداد | طريقة التثبيت |
|
||||
| --------------------- | ---------------- | ------------- | ----------- | ------------------ | ----------------------------------------- |
|
||||
| **كود كلود** | "كلود" | "كلود" | ببيئة | نم |
|
||||
| **مخطوطة OpenAI** | `المخطوطة` | `المخطوطة` | مخصص | نم |
|
||||
| **مصنع الروبوت** | "الروبوت" | "الروبوت" | مخصص | المجمعة/CLI |
|
||||
| **أوبنكلاو** | `مخلب مفتوح` | `مخلب مفتوح` | مخصص | المجمعة/CLI |
|
||||
| **المؤشر** | `المؤشر` | التطبيق | دليل | تطبيق سطح المكتب |
|
||||
| **كلاين** | `كلاين` | `كلاين` | مخصص | نم |
|
||||
| **كيلو كود** | `كيلو` | `الكيلو كود` | مخصص | نم |
|
||||
| **تابع** | `متابعة` | امتداد | دليل | كود مقابل |
|
||||
| **مضادة الجاذبية** | `مضادة الجاذبية` | | ميتوم | أومنيروتي |
|
||||
| **جيثب مساعد الطيار** | `مساعد الطيار` | امتداد | مخصص | كود مقابل |
|
||||
| **الكود مفتوح** | `الرمز مفتوح` | `الرمز مفتوح` | دليل | نم |
|
||||
| **كيرو آي** | `كيرو` | التطبيق/كلي | ميتوم | سطح المكتب/سطر مود | ### مزامنة بصمة CLI (الوكلاء + الإعدادات) |
|
||||
|
||||
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
|
||||
Current list (v3.0.0-rc.16):
|
||||
استخدم `/dashboard/agents` و`Settings > CLI Fingerprint` src/shared/constants/cliCompatProviders.ts.
|
||||
يؤدي ذلك إلى تفاصيل البطاقات الموفر المعتمدة ببطاقات CLI والمعارف القديمة.
|
||||
|
||||
| Tool | ID | Command | Setup Mode | Install Method |
|
||||
| ------------------ | ------------- | ---------- | ---------- | -------------- |
|
||||
| **Claude Code** | `claude` | `claude` | env | npm |
|
||||
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
|
||||
| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
|
||||
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
|
||||
| **Cursor** | `cursor` | app | guide | desktop app |
|
||||
| **Cline** | `cline` | `cline` | custom | npm |
|
||||
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
|
||||
| **Continue** | `continue` | extension | guide | VS Code |
|
||||
| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
|
||||
| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
|
||||
| **OpenCode** | `opencode` | `opencode` | guide | npm |
|
||||
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
|
||||
| معرف واجهة سطر مود | معرف بصمة الإصبع |
|
||||
| ----------------------------------------------------------------------------------------------------- | ---------------- |
|
||||
| `كيلو` | `الكيلو كود` |
|
||||
| `مساعد الطيار` | `جيثب` |
|
||||
| `كلود` / `كوديكس` / `مضاد الجاذبية` / `كيرو` / `المؤشر` / `كلاين` / `opencode` / `droid` / `openclaw` | نفس المعرف |
|
||||
|
||||
### CLI fingerprint sync (Agents + Settings)
|
||||
لا تزال المعرفات القديمة مقبولة للتوافق: `مساعد الطيار`، `كيمي كودينج`، `كوين`.---## Step 1 — Get an OmniRoute API Key
|
||||
|
||||
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
|
||||
This keeps provider IDs aligned with CLI cards and legacy IDs.
|
||||
1. تسجيل الدخول إلى لوحة التحكم OmniRoute →**API Manager**(`/dashboard/api-manager`)
|
||||
2. انقر**إنشاء مفتاح واجهة برمجة التطبيقات**
|
||||
3. أعطته اسمًا (على سبيل المثال، "أدوات cli") وتحديد جميع الأذونات
|
||||
4. انسخ المفتاح — ستحتاج إليه لكل واجهة سطر الأوامر (CLI) أدناه
|
||||
|
||||
| CLI ID | Fingerprint Provider ID |
|
||||
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| `kilo` | `kilocode` |
|
||||
| `copilot` | `github` |
|
||||
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
|
||||
> يبدو مفتاحك كما يلي: `sk-xxxxxxxxxxxxxxxxxx-xxxxxxxxx`---## Step 2 — Install CLI Tools
|
||||
|
||||
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
|
||||
تتطلب جميع المستندات المستندة إلى npm Node.js 18+:```bash
|
||||
|
||||
---
|
||||
# كلود كود (أنثروبي)
|
||||
|
||||
## Step 1 — Get an OmniRoute API Key
|
||||
تثبيت npm -g @anthropic-ai/claude-code
|
||||
|
||||
1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`)
|
||||
2. Click **Create API Key**
|
||||
3. Give it a name (e.g. `cli-tools`) and select all permissions
|
||||
4. Copy the key — you'll need it for every CLI below
|
||||
# مخطوطة OpenAI
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
تثبيت npm -g @openai/codex
|
||||
|
||||
---
|
||||
# الكود المفتوح
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
تثبيت npm -g opencode-ai
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
# كلاين
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
تثبيت npm -g cline
|
||||
|
||||
# OpenAI Codex
|
||||
npm install -g @openai/codex
|
||||
# كيلو كود
|
||||
|
||||
# OpenCode
|
||||
npm install -g opencode-ai
|
||||
تثبيت npm -g كيلوكود
|
||||
|
||||
# Cline
|
||||
npm install -g cline
|
||||
# Kiro CLI (أمازون - يتطلب تجعيد + فك الضغط)
|
||||
|
||||
# KiloCode
|
||||
npm install -g kilocode
|
||||
apt-get install -y unzip # على Debian/Ubuntu
|
||||
حليقة -fsSL https://cli.kiro.dev/install | باش
|
||||
تصدير PATH = "$HOME/.local/bin:$PATH" # إضافة إلى ~/.bashrc```
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
**يؤكد:**```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
opencode --version # x.x.x
|
||||
cline --version # 2.x.x
|
||||
kilocode --version # x.x.x (or: kilo --version)
|
||||
kiro-cli --version # 1.x.x
|
||||
|
||||
**Verify:**
|
||||
|
||||
```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
opencode --version # x.x.x
|
||||
cline --version # 2.x.x
|
||||
kilocode --version # x.x.x (or: kilo --version)
|
||||
kiro-cli --version # 1.x.x
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Set Global Environment Variables
|
||||
|
||||
Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
|
||||
إضافة إلى `~/.bashrc` (أو `~/.zshrc`)، ثم قم ويسمح `المصدر ~/.bashrc`:```bash
|
||||
# نقطة النهاية العالمية OmniRoute
|
||||
تصدير OPENAI_BASE_URL = "http://localhost:20128/v1"
|
||||
تصدير OPENAI_API_KEY = "sk-your-omniroute-key"
|
||||
تصدير ANTHROPIC_BASE_URL = "http://localhost:20128/v1"
|
||||
تصدير ANTHROPIC_API_KEY = "sk-your-omniroute-key"
|
||||
تصدير GEMINI_BASE_URL = "http://localhost:20128/v1"
|
||||
تصدير GEMINI_API_KEY = "sk-your-omniroute-key"```
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
|
||||
---
|
||||
> بالنسبة إلى**الخادم البعيد**، استبدل `localhost:20128` بعنوان IP للخادم أو المجال،
|
||||
> على سبيل المثال `http://192.168.0.15:20128`.---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
# Via CLI:
|
||||
claude config set --global api-base-url http://localhost:20128/v1
|
||||
# عبر سطر الأوامر:
|
||||
مجموعة تكوين كلود - عنوان URL لواجهة برمجة التطبيقات العالمية http://localhost:20128/v1
|
||||
|
||||
# Or create ~/.claude/settings.json:
|
||||
# أو قم بإنشاء ~/.claude/settings.json:
|
||||
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
{
|
||||
"apiBaseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
"apiKey": "مفتاح sk-your-omniroute-"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
EOF```
|
||||
|
||||
**Test:** `claude "say hello"`
|
||||
|
||||
---
|
||||
**اختبار:**`كلود "قل مرحبا"`---
|
||||
|
||||
### OpenAI Codex
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.codex && cat > ~/.codex/config.yaml << EOF
|
||||
model: auto
|
||||
نموذج: السيارات
|
||||
apiKey: sk-your-omniroute-key
|
||||
apiBaseUrl: http://localhost:20128/v1
|
||||
EOF
|
||||
```
|
||||
رابط واجهة برمجة التطبيقات: http://localhost:20128/v1
|
||||
EOF```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
**اختبار:**`مخطوطة "ما هو 2+2؟"'---
|
||||
|
||||
### OpenCode
|
||||
|
||||
@@ -176,19 +150,14 @@ EOF
|
||||
mkdir -p ~/.config/opencode && cat > ~/.config/opencode/config.toml << EOF
|
||||
[provider.openai]
|
||||
base_url = "http://localhost:20128/v1"
|
||||
api_key = "sk-your-omniroute-key"
|
||||
EOF
|
||||
```
|
||||
api_key = "مفتاح sk-omniroute"
|
||||
EOF```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
**اختبار:**`الرمز المفتوح`---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
**وضع سطر الأوامر:**```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"apiProvider": "openai",
|
||||
@@ -196,153 +165,125 @@ mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
"openAiApiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
````
|
||||
|
||||
**VS Code mode:**
|
||||
Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
|
||||
**وضع رمز VS:**
|
||||
إعدادات امتداد Cline ← موفر واجهة برمجة التطبيقات: `متوافق مع OpenAI` ← عنوان URL الأساسي: `http://localhost:20128/v1`
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
|
||||
استخدام لوحة معلومات OmniRoute →**أدوات CLI → Cline → تطبيق المتاح**.---### KiloCode (CLI or VS Code)
|
||||
|
||||
---
|
||||
**وضع سطر مود:**`bash
|
||||
كيلو كود --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key`
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
**إعدادات رمز VS:**```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
````
|
||||
|
||||
---
|
||||
استخدام لوحة معلومات OmniRoute →**CLI → KiloCode → تطبيق تفعيل**.---### Continue (VS Code Extension)
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
model: auto
|
||||
apiBase: http://localhost:20128/v1
|
||||
تحرير `~/.continue/config.yaml`:```yaml
|
||||
النماذج:
|
||||
- الاسم: OmniRoute
|
||||
المزود: openai
|
||||
نموذج: السيارات
|
||||
واجهة برمجة التطبيقات: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
الافتراضي: صحيح```
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
أعد تشغيل VS Code بعد التحرير.---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
```bash
|
||||
# Login to your AWS/Kiro account:
|
||||
kiro-cli login
|
||||
# قم بتسجيل الدخول إلى حساب AWS/Kiro الخاص بك:
|
||||
كيرو كلي تسجيل الدخول
|
||||
|
||||
# The CLI uses its own auth — OmniRoute is not needed as backend for Kiro CLI itself.
|
||||
# Use kiro-cli alongside OmniRoute for other tools.
|
||||
kiro-cli status
|
||||
```
|
||||
# تستخدم واجهة سطر الأوامر (CLI) مصادقة خاصة بها — ليست هناك حاجة إلى OmniRoute كواجهة خلفية لـ Kiro CLI نفسها.
|
||||
# استخدم kiro-cli بجانب OmniRoute لأدوات أخرى.
|
||||
حالة كيرو كلي```
|
||||
|
||||
---
|
||||
|
||||
### Cursor (Desktop App)
|
||||
|
||||
> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
|
||||
> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
|
||||
>**ملاحظة:**يقوم المؤشر بتوجيه الطلبات عبر السحابة الخاصة به. لتكامل OmniRoute،
|
||||
> قم بتمكين**Cloud Endpoint**في إعدادات OmniRoute واستخدم عنوان URL للنطاق العام الخاص بك.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
عبر واجهة المستخدم الرسومية:**الإعدادات → النماذج → مفتاح OpenAI API**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
|
||||
---
|
||||
- عنوان URL الأساسي: `https://your-domain.com/v1`
|
||||
- مفتاح API: مفتاح OmniRoute الخاص بك---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
تقوم لوحة معلومات OmniRoute بأتمتة التكوين لمعظم الأدوات:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
1. انتقل إلى `http://localhost:20128/dashboard/cli-tools`
|
||||
2. قم بتوسيع أي بطاقة أداة
|
||||
3. حدد مفتاح API الخاص بك من القائمة المنسدلة
|
||||
4. انقر فوق**تطبيق التكوين**(إذا تم اكتشاف الأداة على أنها مثبتة)
|
||||
5. أو انسخ مقتطف التكوين الذي تم إنشاؤه يدويًا---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
**Droid**و**OpenClaw**هما وكيلان للذكاء الاصطناعي مدمجان مباشرة في OmniRoute — لا حاجة للتثبيت.
|
||||
يتم تشغيلها كمسارات داخلية وتستخدم توجيه نموذج OmniRoute تلقائيًا.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
- الوصول: `http://localhost:20128/dashboard/agents`
|
||||
- التكوين: نفس المجموعات ومقدمي الخدمات مثل جميع الأدوات الأخرى
|
||||
- لا يلزم تثبيت مفتاح API أو CLI---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| نقطة النهاية | الوصف | استخدم لـ |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | Standard chat (all providers) | All modern tools |
|
||||
| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows |
|
||||
| `/v1/completions` | Legacy text completions | Older tools using `prompt:` |
|
||||
| `/v1/embeddings` | Text embeddings | RAG, search |
|
||||
| `/v1/images/generations` | Image generation | DALL-E, Flux, etc. |
|
||||
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
|
||||
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
|
||||
|
||||
---
|
||||
| `/v1/chat/completions` | الدردشة القياسية (جميع مقدمي الخدمة) | جميع الأدوات الحديثة |
|
||||
| `/v1/الردود` | واجهة برمجة تطبيقات الردود (تنسيق OpenAI) | الدستور الغذائي، سير العمل الوكيل |
|
||||
| `/v1/الإكمال` | إكمال النص القديم | الأدوات القديمة التي تستخدم `المطالبة:` |
|
||||
| `/v1/embeddings` | تضمينات النص | راج، بحث |
|
||||
| `/v1/images/أجيال` | توليد الصور | DALL-E، الجريان، وما إلى ذلك |
|
||||
| `/v1/audio/speech` | تحويل النص إلى كلام | أحد عشر مختبرًا، OpenAI TTS |
|
||||
| `/v1/audio/transcriptions` | تحويل الكلام إلى نص | ديبجرام، الجمعية AI |---
|
||||
|
||||
## استكشاف الأخطاء
|
||||
|
||||
| Error | Cause | Fix |
|
||||
| خطأ | السبب | إصلاح |
|
||||
| ------------------------- | ----------------------- | ------------------------------------------ |
|
||||
| `Connection refused` | OmniRoute not running | `pm2 start omniroute` |
|
||||
| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` |
|
||||
| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` |
|
||||
| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` |
|
||||
| CLI shows "not installed" | Binary not in PATH | Check `which <command>` |
|
||||
| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
|
||||
|
||||
---
|
||||
| `تم رفض الاتصال` | OmniRoute لا يعمل | `pm2 ابدأ في كل الاتجاهات` |
|
||||
| `401 غير مصرح به' | مفتاح API خاطئ | قم بتسجيل الدخول `/dashboard/api-manager` |
|
||||
| `لم يتم تكوين التحرير والسرد` | لا يوجد مجموعة توجيه نشطة | تم الإعداد في `/dashboard/combos` |
|
||||
| `نموذج غير صالح` | الموديل غير موجود في الكتالوج | استخدم "تلقائي" أو حدد "/dashboard/providers" |
|
||||
| يظهر سطر الأوامر "غير مثبت" | ثنائي ليس في PATH | حدد `أي <command>` |
|
||||
| `كيرو كلي: غير موجود` | ليس في المسار | `تصدير المسار = "$HOME/.local/bin:$PATH"` |---
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
```bash
|
||||
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
|
||||
# تثبيت جميع واجهات سطر الأوامر (CLI) وتكوين OmniRoute (استبدلها بمفتاحك وعنوان URL الخاص بالخادم)
|
||||
OMNIROUTE_URL="http://localhost:20128/v1"
|
||||
OMNIROUTE_KEY="sk-your-omniroute-key"
|
||||
|
||||
npm install -g @anthropic-ai/claude-code @openai/codex opencode-ai cline kilocode
|
||||
تثبيت npm -g @anthropic-ai/clude-code @openai/codex opencode-ai cline Kilocode
|
||||
|
||||
# Kiro CLI
|
||||
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
|
||||
# كيرو كلي
|
||||
apt-get install -y unzip 2>/dev/null; حليقة -fsSL https://cli.kiro.dev/install | باش
|
||||
|
||||
# Write configs
|
||||
# كتابة التكوينات
|
||||
mkdir -p ~/.claude ~/.codex ~/.config/opencode ~/.continue
|
||||
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
cat >> ~/.bashrc << EOF
|
||||
export OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
export OPENAI_API_KEY="$OMNIROUTE_KEY"
|
||||
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
القط >> ~/.bashrc << EOF
|
||||
تصدير OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
تصدير OPENAI_API_KEY = "$OMNIROUTE_KEY"
|
||||
تصدير ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
تصدير ANTHROPIC_API_KEY = "$OMNIROUTE_KEY"
|
||||
EOF
|
||||
|
||||
source ~/.bashrc
|
||||
echo "✅ All CLIs installed and configured for OmniRoute"
|
||||
```
|
||||
المصدر ~/.bashrc
|
||||
صدى " ✅ تم تثبيت جميع واجهات سطر الأوامر (CLI) وتكوينها لـ OmniRoute"```
|
||||
````
|
||||
|
||||
@@ -1,24 +1,16 @@
|
||||
# omniroute — Codebase Documentation (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [hi](../../hi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇷 [tr](../../tr/docs/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
---
|
||||
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
> دليل شامل ومناسب للمبتدئين إلى مدير المدير AI**omniroute**متعدد الموفرين.---## 1. What Is omniroute?
|
||||
|
||||
---
|
||||
omniroute هو**جهاز وكيل التوجيه**يقع بين عملاء الذكاء الاصطناعي (Claude CLI، وCodex، وCursor IDE، وما إلى ذلك) وموفري الذكاء الاصطناعي (Anthropic، وGoogle، وOpenAI، وAWS، وGitHub، وما إلى ذلك). يحل مشكلة واحدة كبيرة:
|
||||
|
||||
## 1. What Is omniroute?
|
||||
> **يتحدث عملاء الذكاء الاصطناعي المختلفون "لغات" مختلفة (تنسيقات واجهة برمجة التطبيقات)، ويتوقع مقدمو خدمات الذكاء الاصطناعي المختلفون "لغات مختلفة" أيضاً.**يترجم المسار الشامل بما فيه الكفاية.
|
||||
|
||||
omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem:
|
||||
|
||||
> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
|
||||
|
||||
Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate.
|
||||
|
||||
---
|
||||
|
||||
## 2. Architecture Overview
|
||||
فكر في الأمر التالي مترجم عالمي في الأمم المتحدة - يمكن لأي مندوبات أي لغة، والمترجم هل يمكن أن يترجمها لأي مندوب آخر.---## 2. Architecture Overview
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -65,44 +57,38 @@ graph LR
|
||||
|
||||
### Core Principle: Hub-and-Spoke Translation
|
||||
|
||||
All format translation passes through **OpenAI format as the hub**:
|
||||
تمر جميع ترجمةات عبر**تنسيق OpenAI كمركز**:`
|
||||
تنسيق العميل → [OpenAI Hub] → تنسيق الموفر (طلب)
|
||||
تنسيق الموفر → [OpenAI Hub] → تنسيق العميل (الاستجابة)`
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
This means you only need **N translators** (one per format) instead of **N²** (every pair).
|
||||
|
||||
---
|
||||
هذا يعني أنك تحتاج فقط إلى مترجمين**N**(واحد لكل تنسيق) بدلاً من**N²**(كل زوج).---
|
||||
|
||||
## 3. Project Structure
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
````
|
||||
الطريق الشامل/
|
||||
├── open-sse/ ← مكتبة الوكيل الأساسية (محمول، لا إطاري)
|
||||
│ ├── Index.js ← نقطة الدخول الرئيسية، تصدر كل شيء
|
||||
│ ├── التكوين/ ← التكوين والثوابت
|
||||
│ ├── المنفذون/ ← تنفيذ الطلب الخاص بالمزود
|
||||
│ ├── معالجات/ ← طلب تنسيق التعامل
|
||||
│ ├── الخدمات/ ← منطق الأعمال (المصادقة، النماذج، الاحتياطي، الاستخدام)
|
||||
│ ├── مترجم/ ← تنسيق محرك الترجمة
|
||||
│ │ ├── طلب/ ← طلب مترجمين (8 ملفات)
|
||||
│ │ ├── استجابة/ ← مترجمو الاستجابة (7 ملفات)
|
||||
│ │ └── مساعدون/ ← أدوات الترجمة المشتركة (6 ملفات)
|
||||
│ └── المرافق/ ← وظائف المرافق
|
||||
├── src/ ← طبقة التطبيق (وقت تشغيل Express/Worker)
|
||||
│ ├── التطبيق/ ← واجهة مستخدم الويب، مسارات واجهة برمجة التطبيقات، البرامج الوسيطة
|
||||
│ ├── lib/ ← قاعدة البيانات والمصادقة وكود المكتبة المشتركة
|
||||
│ ├── mitm/ ← أدوات الوكيل الوسيطة
|
||||
│ ├── النماذج/ ← نماذج قواعد البيانات
|
||||
│ ├── مشترك/ ← أدوات مساعدة مشتركة (مغلفات حول open-sse)
|
||||
│ ├── sse/ ← معالجات نقطة النهاية SSE
|
||||
│ └── المتجر/ ← إدارة الدولة
|
||||
├── البيانات/ ← بيانات وقت التشغيل (بيانات الاعتماد والسجلات)
|
||||
│ └── Provider-credentials.json (تجاوز بيانات الاعتماد الخارجية، gitignored)
|
||||
└── اختبار/ ← اختبار المرافق```
|
||||
|
||||
---
|
||||
|
||||
@@ -110,45 +96,40 @@ omniroute/
|
||||
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
The **single source of truth** for all provider configuration.
|
||||
**المصدر الوحيد للحقيقة**لجميع إعدادات الموفر.
|
||||
|
||||
| File | Purpose |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
|
||||
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
|
||||
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
|
||||
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
|
||||
|
||||
#### Credential Loading Flow
|
||||
| ملف | الغرض |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `الثوابت.ts` | كائن `PROVIDERS` يحتوي على عناوين URL الأساسية وبيانات اعتماد OAuth (الافتراضية) والرؤوس ومطالبات النظام الافتراضية لكل موفر. يحدد أيضًا `HTTP_STATUS` و`ERROR_TYPES` و`COOLDOWN_MS` و`BACKOFF_CONFIG` و`SKIP_PATTERNS`. |
|
||||
| "credentialLoader.ts" | يقوم بتحميل بيانات الاعتماد الخارجية من "data/provider-credentials.json" ويدمجها في الإعدادات الافتراضية المضمنة في "PROVIDERS". يحافظ على الأسرار خارج نطاق التحكم بالمصدر مع الحفاظ على التوافق مع الإصدارات السابقة. |
|
||||
| `providerModels.ts` | سجل النموذج المركزي: الأسماء المستعارة لموفر الخرائط → معرفات النموذج. وظائف مثل `getModels()` و`getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | تعليمات النظام التي تم إدخالها في طلبات الدستور الغذائي (قيود التحرير، قواعد الاختبار، سياسات الموافقة). |
|
||||
| `defaultThinkingSignature.ts` | توقيعات "التفكير" الافتراضية لنماذج كلود وجيميني. |
|
||||
| `olmaModels.ts` | تعريف المخطط لنماذج أولاما المحلية (الاسم، الحجم، العائلة، التكميم). |#### Credential Loading Flow
|
||||
|
||||
```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
|
||||
```
|
||||
مخطط انسيابي TD
|
||||
A["يبدأ التطبيق"] --> B["constants.ts يحدد مقدمي الخدمة\nبإعدادات افتراضية مضمنة"]
|
||||
B --> C{"data/provider-credentials.json\nexists؟"}
|
||||
ج -->|نعم| D["credentialLoader يقرأ JSON"]
|
||||
ج -->|لا| E["استخدام الإعدادات الافتراضية المشفرة"]
|
||||
D --> F{"لكل موفر في JSON"}
|
||||
F --> G{"الموفر موجود\nفي الموفرين؟"}
|
||||
ز -->|لا| H["تحذير السجل، تخطي"]
|
||||
ز -->|نعم| أنا{"القيمة هي كائن؟"}
|
||||
أنا -->|لا| J["تحذير السجل، تخطي"]
|
||||
أنا -->|نعم| K["دمج معرف العميل، ClientSecret،\ntokenUrl، authUrl، RefreshUrl"]
|
||||
ك --> ف
|
||||
ح --> ف
|
||||
ي --> ف
|
||||
F -->|تم| L["الموفرون جاهزون\nببيانات اعتماد مدمجة"]
|
||||
ه --> ل```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Executors (`open-sse/executors/`)
|
||||
|
||||
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
|
||||
|
||||
```mermaid
|
||||
يقوم المنفذون بتغليف**المنطق الخاص بالمزود**باستخدام**نمط الإستراتيجية**. يتجاوز كل منفذ الأساليب الأساسية حسب الحاجة.```mermaid
|
||||
classDiagram
|
||||
class BaseExecutor {
|
||||
+buildUrl(model, stream, options)
|
||||
@@ -194,42 +175,35 @@ classDiagram
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
````
|
||||
|
||||
| Executor | Provider | Key Specializations |
|
||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers |
|
||||
| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") |
|
||||
| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
|
||||
| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh |
|
||||
| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking |
|
||||
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
|
||||
| `index.ts` | — | Factory: maps provider name → executor class, with default fallback |
|
||||
| المنفذ | مقدم | التخصص الرئيسي |
|
||||
| -------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------ |
|
||||
| `base.ts` | — | قاعدة الملخصات: إنشاء عنوان URL، والرؤوس، ومنطقة إعادة المحاولة، وتحديث بيانات الاعتماد |
|
||||
| `default.ts` | كلود، جيميني، أوبن آي آي، جي إل إم، كيمي، ميني ماكس | تحديث رمز OAuth العام للموفرين الكلاسيكيين |
|
||||
| `مكافحة الجاذبية.ts` | جوجل كلود كود | إنشاء معرف المشروع/الجلسة، وإرجاع عناوين URL الإعلامية، بعد محاولة تحديد موقع رسائل الخطأ ("إعادة بعد 2 ساعة و7 دقائق و23 ثانية") |
|
||||
| `cursor.ts` | منطقة تطوير متعددة للمؤشر | **الأكثر مخاطرًا**: مصادقة التسجيل الاختباري SHA-256، وترميز طلب Protobuf، وEventStream ثنائي → تحليل اتصال SSE |
|
||||
| `codex.ts` | OpenAI Codex | حجم تعليمات النظام، وإدارة مستويات التفكير، تجديد المعلمات غير المدعومة |
|
||||
| `الجوزاء-cli.ts` | جوجل الجوزاء CLI | إنشاء عنوان URL مخصص (`streamGenerateContent`)، وتحديث رمز OAuth المميز لـ Google |
|
||||
| `جيثب.ts` | جيثب مساعد الطيار | نظام رمزي ثنائي (GitHub OAuth + Copilot token)، محاكاة رأس VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | التحليل الثنائي لـ AWS EventStream، وإطارات أحداث AMZN، والتقدير المميز |
|
||||
| `index.ts` | — | المصنع: اسم موفر ← فئة المنفذ، مع خيار بديل افتراضي | ---### 4.3 Handlers (`open-sse/handlers/`) |
|
||||
|
||||
---
|
||||
**طبقة تأتي**— تترتب على الترجمة والتنفيذ والتدفق ويسبب سبب.
|
||||
|
||||
### 4.3 Handlers (`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 |
|
||||
|
||||
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
|
||||
|
||||
| File | Purpose |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. |
|
||||
| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. |
|
||||
| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. |
|
||||
| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. |
|
||||
|
||||
#### Request Lifecycle (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
|
||||
Client->>chatCore: Request (any format)
|
||||
chatCore->>chatCore: Detect source format
|
||||
@@ -256,15 +230,14 @@ sequenceDiagram
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Services (`open-sse/services/`)
|
||||
|
||||
Business logic that supports the handlers and executors.
|
||||
|
||||
| File | Purpose |
|
||||
منطق الأعمال الذي يدعم المعالجات والمنفذين.| File | Purpose |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
|
||||
| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
|
||||
@@ -300,7 +273,7 @@ sequenceDiagram
|
||||
Cache-->>R1: New access token
|
||||
Cache-->>R2: Same access token (shared)
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
````
|
||||
|
||||
#### Account Fallback State Machine
|
||||
|
||||
@@ -348,22 +321,18 @@ flowchart LR
|
||||
|
||||
### 4.5 Translator (`open-sse/translator/`)
|
||||
|
||||
The **format translation engine** using a self-registering plugin system.
|
||||
|
||||
#### الهندسة
|
||||
|
||||
```mermaid
|
||||
**محرك استعداد**باستخدام نظام التوقيع الذاتي.#### الكائنات```mermaid
|
||||
graph TD
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
|
||||
subgraph "Response Translation"
|
||||
I["Claude → OpenAI"]
|
||||
@@ -374,182 +343,149 @@ graph TD
|
||||
N["OpenAI → Antigravity"]
|
||||
O["OpenAI → Responses"]
|
||||
end
|
||||
```
|
||||
|
||||
| Directory | Files | Description |
|
||||
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. |
|
||||
| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. |
|
||||
| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. |
|
||||
| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
````
|
||||
|
||||
#### Key Design: Self-Registering Plugins
|
||||
|
||||
```javascript
|
||||
| الدليل | ملفات | الوصف |
|
||||
| ------------ | ------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `طلب/` | 8 مترجمين | تحويل أجسام بين الصيغ. يتم تسجيل كل ملف ذاتيًا عبر "التسجيل (من، إلى، fn)" عند الاستيراد. |
|
||||
| `الاستجابة/` | 7 مترجمين | تحويل قطع المضخّم بين الصيغة. للتعرف على أنواع أحداث SSE وكتل التفكير وأدوات الأدوات. |
|
||||
| `المساعدين/` | 6 مساعدين | الأداة المساعدة المشتركة: `cludeHelper` (استخراج النظام، البحث المطلوب البحث)، `geminiHelper` (تخطيط الأجزاء/المحتويات)، `openaiHelper` (خيار مناسب)، `toolCallHelper` (إنشاء المعرف، البحث المطلوب المطلوبة)، `maxTokensHelper`، `responsesApiHelper`. |
|
||||
| `index.ts` | — | ترجمة المحرك: `translateRequest()`، `translateResponse()`، إدارة الحالة، التسجيل. |
|
||||
| `formats.ts` | — | ثوابت عادة: `OPENAI`، `CLAUDE`، `GEMINI`، `ANTIGRAVITY`، `KIRO`، `CURSOR`، `OPENAI_RESPONSES`. |#### التصميم الرئيسي: المكونات الإضافية ذاتية التسجيل```javascript
|
||||
// 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/`)
|
||||
|
||||
| File | Purpose |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. |
|
||||
| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. |
|
||||
| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). |
|
||||
| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. |
|
||||
| `requestLogger.ts` | File-based request logging (opt-in via `ENABLE_REQUEST_LOGS=true`). Creates session folders with numbered files: `1_req_client.json` → `7_res_client.txt`. All I/O is async (fire-and-forget). Masks sensitive headers. |
|
||||
| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. |
|
||||
| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. |
|
||||
| ملف | الحصاد |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------- |
|
||||
| "خطأ.ts" | إنشاء كلمات للأخطاء (تنسيق متوافق مع OpenAI)، وسبب المشكلة، واستخراجها، وحاول إعادة محاولة Antigravity من رسائل الخطأ، وأخطاء SSE. |
|
||||
| "stream.ts" | **SSE Transform Stream**— خط أنابيب البث الأساسي. وضعان: "الترجمة" (ترجمة كاملة) و"العبور" (التطبيع + الطلب المستخدم). وأخذ بعين الاعتبار التخزين المؤقت للقطعة وتقدير استخدامها وتتبع طول الفيديو. تجنب مثيلات وحدة التشفير/وحدة فك التشفير لكل حالة DC المشتركة. |
|
||||
| `streamHelpers.ts` | SSE ذات المستوى المنخفض: `parseSSELine` (متسامح مع المسافات البيضاء)، `hasValuableContent` ( تصفية أدوات الفارغة لـ OpenAI/Claude/Gemini)، `fixInvalidId`، `formatSSE` (تسلسل SSE مدرك للتنسيق مع `perf_metrics`). |
|
||||
| `usageTracking.ts` | استخدام النسخة المميزة من أي تنسيق (Claude/OpenAI/Gemini/Responses)، والاستعانة بـ DNS لكل رمز مميز للأداة/الرسالة، والمخزن المؤقت (هامش أمان 2000 رمز مميز)، وتصفية الخاصيات بالتنسيق، وتسجيل وحدة التحكم مع ANSI. |
|
||||
| `requestLogger.ts` | تسجيل الطلب إلى الملف (قم بالاشتراك عبر `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 |
|
||||
|
||||
#### SSE Streaming Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
|
||||
style A fill:#f9f,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
|
||||
```
|
||||
|
||||
#### Request Logger Session Structure
|
||||
|
||||
```
|
||||
|
||||
logs/
|
||||
└── claude_gemini_claude-sonnet_20260208_143045/
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
```
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.7 Application Layer (`src/`)
|
||||
|
||||
| Directory | Purpose |
|
||||
| الدليل | الحصاد |
|
||||
| ------------- | ---------------------------------------------------------------------- |
|
||||
| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers |
|
||||
| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared |
|
||||
| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic |
|
||||
| `src/models/` | Database model definitions |
|
||||
| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) |
|
||||
| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes |
|
||||
| `src/store/` | Application state management |
|
||||
| `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 البارزة
|
||||
|
||||
#### Notable API Routes
|
||||
|
||||
| Route | Methods | Purpose |
|
||||
| الطريق | طرق | الحصاد |
|
||||
| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- |
|
||||
| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider |
|
||||
| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider |
|
||||
| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency |
|
||||
| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
|
||||
| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
|
||||
| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
|
||||
| `/api/sessions` | GET | Active session tracking and metrics |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
|
||||
---
|
||||
|
||||
## 5. Key Design Patterns
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | CRUD للنماذج المتخصصة لكل |
|
||||
| `/api/models/catalog` | احصل على | مجمع كتالوج لجميع الارتباطات (الدردشة، التضمين، الصورة، تخصيص) مجمعة حسب الموفر |
|
||||
| `/api/settings/proxy` | الحصول على/وضع/حذف | الجاهزة التفصيلي (`العالمي/الموفرون/المجموعات/المفاتيح`) |
|
||||
| `/api/settings/proxy/test` | مشاركة | التحقق من صحة الاتصال الوكيل وإرجاع IP/زمن الوصول العام |
|
||||
| `/v1/providers/[provider]/chat/completions` | مشاركة | عمليات البحث عن الاختيار المناسب لكل شخص مع التحقق من صحة النموذج |
|
||||
| `/v1/providers/[provider]/embeddings` | مشاركة | عمليات تضمين التخصص حسب الاختيار مع نموذج التحقق من الصحة |
|
||||
| `/v1/providers/[provider]/images/ Generations` | مشاركة | إنشاء صور مخصصة لكل وثيقة معتمدة من نموذج صحة |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | قائمة IP الخاصة بها/إدارة القائمة المحظورة |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | المحددة المحددة الرمز (العبور/التلقائي/المخصص/التكيفي) |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | القطع المؤقتة لأدوات البناء العالمية |
|
||||
| `/api/sessions` | احصل على | تحديد العضوية ومعاييرها |
|
||||
| `/api/rate-limits` | احصل على | الحالة لا يمكن تعديلها لكل حساب |---## 5. Key Design Patterns
|
||||
|
||||
### 5.1 Hub-and-Spoke Translation
|
||||
|
||||
All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs.
|
||||
تتم ترجمة جميع الاحتمالات من خلال**تنسيق OpenAI كمحور**. لا تتطلب إضافة موفر جديد سوى كتابة**زوج واحد**من المترجمين (من/ إلى OpenAI)، وليس عدد N من المترجمين.### 5.2 Executor Strategy Pattern
|
||||
|
||||
### 5.2 Executor Strategy Pattern
|
||||
كل ما لديها فئة تنفيذية مخصصة ترث من "BaseExecutor". تم تصنيع المصنع الموجود في "executors/index.ts" وبالتالي أصبح المصنع جاهزًا في وقت التشغيل.### 5.3 نظام البرنامج الإضافي للتسجيل الذاتي
|
||||
|
||||
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
|
||||
وحدات المترجمة نفسها عند الاستيراد عبر ``تسجيل ()'. إن إضافة مترجم جديد يعني مجرد إنشاء ملف واستيراده.### 5.4 Account Fallback with Exponential Backoff
|
||||
|
||||
### 5.3 Self-Registering Plugin System
|
||||
عندما يقوم بتقديم خدمة بإرجاع 429/401/500، يمكن أن يتكامل مع الحساب التالي، مع تطبيق أحدث الحداثات الأسية (1ث → 2ث → 4ث → 2 دقيقة الضرر التام).### 5.5 Combo Model Chains
|
||||
|
||||
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
|
||||
يقوم "التحرير والسرد" بتجميع سلاسل "المزود/النموذج" حاسوبياً. في حالة الفشل الأول، يتم الرجوع إلى المنتج الأصلي.### 5.6 الترجمة المتدفقة ذات الحالة
|
||||
|
||||
### 5.4 Account Fallback with Exponential Backoff
|
||||
الحفاظ على ترجمة الأجزاء ذات الحالة عبر SSE (تتبع كتلة التفكير، وتراكم الاتصال بالجهة، وفهرسة كتلة المحتوى) عبر تقنية `initState()`.### 5.7 المخزن المؤقت لسلامة الاستخدام
|
||||
|
||||
When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
|
||||
تم إضافة مخزن مؤقت مكون من 2000 رمز مميز إلى الحد الأقصى من الاستخدام لمساعدة العملاء على الوصول إلى حدود النافذة بسبب الحمل الزائد من مطالبات النظام وترجمة السائقين.---## 6. Supported Formats
|
||||
|
||||
### 5.5 Combo Model Chains
|
||||
|
||||
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
|
||||
|
||||
### 5.6 Stateful Streaming Translation
|
||||
|
||||
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
|
||||
|
||||
### 5.7 Usage Safety Buffer
|
||||
|
||||
A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation.
|
||||
|
||||
---
|
||||
|
||||
## 6. Supported Formats
|
||||
|
||||
| Format | Direction | Identifier |
|
||||
| التنسيق | | المعرف |
|
||||
| ----------------------- | --------------- | ------------------ |
|
||||
| OpenAI Chat Completions | source + target | `openai` |
|
||||
| OpenAI Responses API | source + target | `openai-responses` |
|
||||
| Anthropic Claude | source + target | `claude` |
|
||||
| Google Gemini | source + target | `gemini` |
|
||||
| Google Gemini CLI | target only | `gemini-cli` |
|
||||
| Antigravity | source + target | `antigravity` |
|
||||
| AWS Kiro | target only | `kiro` |
|
||||
| Cursor | target only | `cursor` |
|
||||
| استكمالات الدردشة OpenAI | المصدر + الهدف | `أوبيني` |
|
||||
| برمجة تطبيقات استجابات OpenAI | المصدر + الهدف | `الردود المفتوحة` |
|
||||
| أنثروب كلود | المصدر + الهدف | "كلود" |
|
||||
| جوجل الجوزاء | المصدر + الهدف | `الجوزاء` |
|
||||
| جوجل الجوزاء CLI | الهدف فقط | `الجوزاء-كلي` |
|
||||
| مكافحة الجاذبية | المصدر + الهدف | `مضادة الجاذبية` |
|
||||
| أوس كيرو | الهدف فقط | `كيرو` |
|
||||
| |مؤثر الهدف فقط | `المؤشر` |---## 7. Supported Providers
|
||||
|
||||
---
|
||||
|
||||
## 7. Supported Providers
|
||||
|
||||
| Provider | Auth Method | Executor | Key Notes |
|
||||
| مقدم | طريقة المصادقة | المنفذ | المذكرة الرئيسية |
|
||||
| ------------------------ | ---------------------- | ----------- | --------------------------------------------- |
|
||||
| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header |
|
||||
| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint |
|
||||
| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing |
|
||||
| OpenAI | API key | Default | Standard Bearer auth |
|
||||
| Codex | OAuth | Codex | Injects system instructions, manages thinking |
|
||||
| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking |
|
||||
| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing |
|
||||
| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
|
||||
| Qwen | OAuth | Default | Standard auth |
|
||||
| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
|
||||
| OpenRouter | API key | Default | Standard Bearer auth |
|
||||
| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` |
|
||||
| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint |
|
||||
| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint |
|
||||
|
||||
---
|
||||
|
||||
## 8. Data Flow Summary
|
||||
| أنثروب كلود | واجهة برمجة التطبيقات الرئيسية أو OAuth | افتراضي | يستخدم رأس `x-api-key` |
|
||||
| جوجل الجوزاء | واجهة برمجة التطبيقات الرئيسية أو OAuth | افتراضي | يستخدم رأس `x-goog-api-key` |
|
||||
| جوجل الجوزاء CLI | أووث | الجوزاء كلي | يستخدم نقطة نهاية "streamGenerateContent" |
|
||||
| مكافحة الجاذبية | أووث | مكافحة الجاذبية | شراء عناوين URL الخاصة بها، إعادة محاولة البحث عن المواقع |
|
||||
| أوبن آي | واجهة برمجة التطبيقات الرئيسية | افتراضي | مصادقة الحامل |
|
||||
| الدستور الغذائي | أووث | الدستور الغذائي | يدخل تعليمات النظام ويدير التفكير |
|
||||
| جيثب مساعد الطيار | OAuth + رمز مساعد الطيار | جيثب | رمز مزدوج، محاكاة رأس VSCode |
|
||||
| كيرو (AWS) | AWS SSO OIDC أو اجتماعي | كيرو | تحليل دفق الأحداث الثنائية |
|
||||
| بيئة تطوير متكاملة للمؤشر | تصويت الاختياري | |مؤثر ترميز Protobuf، الجلسات الاختباري SHA-256 |
|
||||
| كوين | أووث | افتراضي | المصادقة القياسية |
|
||||
| قدير | OAuth (أساسي + حامل) | افتراضي | رأس المصادقة |
|
||||
| اوبن راوتر | واجهة برمجة التطبيقات الرئيسية | افتراضي | مصادقة الحامل |
|
||||
| جي إل إم، كيمي، ميني ماكس | واجهة برمجة التطبيقات الرئيسية | افتراضي | متوافق مع كلود، استخدم `x-api-key` |
|
||||
| `متوافق مع openai-*` | واجهة برمجة التطبيقات الرئيسية | افتراضي | برمجة: أي نقطة نهاية متوافقة مع OpenAI |
|
||||
| `متوافق مع البشر-*` | واجهة برمجة التطبيقات الرئيسية | افتراضي | برمجة: أي نقطة نهاية متوافقة مع كلود |---## 8. Data Flow Summary
|
||||
|
||||
### Streaming Request
|
||||
|
||||
@@ -566,7 +502,7 @@ flowchart LR
|
||||
I --> J["formatSSE()"]
|
||||
J --> K["Client receives\ntranslated SSE"]
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
````
|
||||
|
||||
### Non-Streaming Request
|
||||
|
||||
|
||||
@@ -1,158 +1,127 @@
|
||||
# Test Coverage Plan (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [hi](../../hi/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md) · 🇹🇷 [tr](../../tr/docs/COVERAGE_PLAN.md)
|
||||
|
||||
---
|
||||
|
||||
Last updated: 2026-03-28
|
||||
آخر تحديث: 2026-03-28##
|
||||
|
||||
## Baseline
|
||||
هناك تفاصيل تفصيلية متعددة حول كيفية حساب التقرير. للتخطيط، واحد منهم فقط مفيد.
|
||||
|
||||
There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
|
||||
| متري | النطاق | بقدر / سطور | فرع | الوظائف | تعليقات |
|
||||
| ------------ | -------------------------------------- | ----------: | -----: | ------: | ----------------------------------------------- |
|
||||
| تراث | اختبار تشغيل npm القديم: غلاف | 79.42% | 75.15% | 67.94% | مضخم: يحصي اختبارات الاختبار ويستبعد `open-sse` |
|
||||
| التشخيص | المصدر فقط، التمييز و السبب `open-sse` | 68.16% | 63.55% | 64.06% | مفيد فقط لعزل `src/**` |
|
||||
| خط الأساس له | المصدر فقط، لغرض القسم `open-sse` | 56.95% | 66.05% | 57.80% | هذا هو خط الأساس لتحسين المشروع |
|
||||
|
||||
| Metric | Scope | Statements / Lines | Branches | Functions | Notes |
|
||||
| -------------------- | ----------------------------------------------------- | -----------------: | -------: | --------: | --------------------------------------------------- |
|
||||
| Legacy | Old `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Inflated: counts test files and excludes `open-sse` |
|
||||
| Diagnostic | Source-only, excluding tests and excluding `open-sse` | 68.16% | 63.55% | 64.06% | Useful only to isolate `src/**` |
|
||||
| Recommended baseline | Source-only, excluding tests and including `open-sse` | 56.95% | 66.05% | 57.80% | This is the project-wide baseline to improve |
|
||||
خط الأساس به هو الرقم المطلوب وتحسينه.## Rules
|
||||
|
||||
The recommended baseline is the number to optimize against.
|
||||
- تستهدف تحديد الملفات المصدر، وليس على "الاختبارات/\*\*".
|
||||
- `open-sse/**` هو جزء من المنتج ويجب أن يختفي في نطاقه.
|
||||
- يجب ألا تحدد الكود الجديد من المناطق التي تم لمسها.
|
||||
- تفضيل الاختبار ونتائج الجهة على تفاصيل التنفيذ.
|
||||
- تفضيلات متطلبات بيانات SQLite المطر والتركيبات الصغيرة على الارتباطات المتخصصة لـ src/lib/db/\*\*`.## مجموعة الأوامر الحالية
|
||||
|
||||
## Rules
|
||||
- `اختبار تشغيل npm: التغطية`
|
||||
- بوابة المصدر الرئيسي لمجموعة اختبار الوحدة
|
||||
- إنشاء ملخص النص، وhtml، وملخص json، ولكوف
|
||||
- `تغطية تشغيل npm: تقرير`
|
||||
- تقرير مفصل لملف الآخر من العملية الأخيرة
|
||||
- `اختبار تشغيل npm:التغطية:تراث`
|
||||
- لتحدث التاريخية فقط## المعالم
|
||||
|
||||
- Coverage targets apply to source files, not to `tests/**`.
|
||||
- `open-sse/**` is part of the product and must remain in scope.
|
||||
- New code should not reduce coverage in touched areas.
|
||||
- Prefer testing behavior and branch outcomes over implementation details.
|
||||
- Prefer temp SQLite databases and small fixtures over broad mocks for `src/lib/db/**`.
|
||||
| المرحلة | الهدف | التركيز |
|
||||
| --------------- | ------------: | ------------------------------------------------- |
|
||||
| المرحلة 1 | 60% لذلك/سطور | مكاسب سريعة وتغطية شاملة لمختلف الفئات |
|
||||
| المرحلة الثانية | 65% لذلك/سطور | أسس قاعدة البيانات والطريق |
|
||||
| المرحلة 3 | 70% لذلك/سطور | التحقق من صحة الموفر وتحليلات الاستخدام |
|
||||
| الخطوة الرابعة | 75% لذلك/سطور | مترجمون ومساعدون `open-sse' |
|
||||
| المرحلة الخامسة | 80% لذلك/سطور | رامات وروعة الزجاجة `open-sse` |
|
||||
| المرحلة السادسة | 85% لذلك/سطور | الحالات القصوى، الديون الدينية، وأجنحة الانحدار |
|
||||
| المرحلة السابعة | 90% لذلك/سطور | الاجتياح النهائي، الإغلاق الشامل، السقاطة الساكنة |
|
||||
|
||||
## Current command set
|
||||
يجب أن ترتكز الجذور والوظائف مع كل مرحلة، ولكن الهدف الأساسي الثابت هو البيانات/السطور.## النقاط الساخنة ذات الأولوية
|
||||
|
||||
- `npm run test:coverage`
|
||||
- Main source coverage gate for the unit test suite
|
||||
- Generates `text-summary`, `html`, `json-summary`, and `lcov`
|
||||
- `npm run coverage:report`
|
||||
- Detailed file-by-file report from the latest run
|
||||
- `npm run test:coverage:legacy`
|
||||
- Historical comparison only
|
||||
توفر هذه الملفات أو المناطق أفضل عائد للمراحل التالية:1. "فتح sse/معالجات".
|
||||
|
||||
## Milestones
|
||||
- `chatCore.ts` بنسبة 7.57%
|
||||
- الدليل الشامل بنسبة 29.07% 2.`open-sse/translator/request`
|
||||
- الرد المرسل إليه 36.39%
|
||||
- لا يزال العديد من المترجمين على مقربة من تغطية ما يكفي من رقم واحد
|
||||
|
||||
| Phase | Target | Focus |
|
||||
| ------- | ---------------------: | ------------------------------------------------- |
|
||||
| Phase 1 | 60% statements / lines | Quick wins and low-risk utility coverage |
|
||||
| Phase 2 | 65% statements / lines | DB and route foundations |
|
||||
| Phase 3 | 70% statements / lines | Provider validation and usage analytics |
|
||||
| Phase 4 | 75% statements / lines | `open-sse` translators and helpers |
|
||||
| Phase 5 | 80% statements / lines | `open-sse` handlers and executor branches |
|
||||
| Phase 6 | 85% statements / lines | Harder edge cases, branch debt, regression suites |
|
||||
| Phase 7 | 90% statements / lines | Final sweep, gap closure, strict ratchet |
|
||||
|
||||
Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
|
||||
|
||||
## Priority hotspots
|
||||
|
||||
These files or areas offer the best return for the next phases:
|
||||
|
||||
1. `open-sse/handlers`
|
||||
- `chatCore.ts` at 7.57%
|
||||
- Overall directory at 29.07%
|
||||
2. `open-sse/translator/request`
|
||||
- Overall directory at 36.39%
|
||||
- Many translators are still near single-digit coverage
|
||||
3. `open-sse/translator/response`
|
||||
- Overall directory at 8.07%
|
||||
4. `open-sse/executors`
|
||||
- Overall directory at 36.62%
|
||||
5. `src/lib/db`
|
||||
- `models.ts` at 20.66%
|
||||
- `registeredKeys.ts` at 34.46%
|
||||
- `modelComboMappings.ts` at 36.25%
|
||||
- `settings.ts` at 46.40%
|
||||
- `webhooks.ts` at 33.33%
|
||||
6. `src/lib/usage`
|
||||
- `usageHistory.ts` at 21.12%
|
||||
- `usageStats.ts` at 9.56%
|
||||
- `costCalculator.ts` at 30.00%
|
||||
7. `src/lib/providers`
|
||||
- `validation.ts` at 41.16%
|
||||
8. Low-risk utility and API files for early gains
|
||||
3. "open-sse/translator/response".
|
||||
- الرد المرسل إليه 8.07%
|
||||
4. "open-sse/المنفذين".
|
||||
- البريد المرسل إليه 36.62% 5.`src/lib/db`
|
||||
- `models.ts` بنسبة 20.66%
|
||||
- "المفاتيح الجديدة" بنسبة 34.46%
|
||||
- `modelComboMappings.ts` بنسبة 36.25%
|
||||
- `settings.ts` عند 46.40%
|
||||
- `webhooks.ts' بنسبة 33.33%
|
||||
6.`src/lib/usage`
|
||||
- `usageHistory.ts` بنسبة 21.12%
|
||||
- `usageStats.ts` بنسبة 9.56%
|
||||
- `costCalculator.ts` بنسبة 30.00% 7.`src/lib/providers`
|
||||
- `validation.ts` بنسبة 41.16%
|
||||
5. ملفات المساعدة وواجهة برمجة التطبيقات (API) ذات القدرة الضعيفة على فقدان القليل
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`## قائمة التحقق من التنفيذ### Phase 1: 56.95% -> 60%
|
||||
|
||||
## Execution checklist
|
||||
|
||||
### Phase 1: 56.95% -> 60%
|
||||
|
||||
- [x] Fix coverage metric so it reflects source code instead of test files
|
||||
- [x] Keep a legacy coverage script for comparison
|
||||
- [x] Record the baseline and hotspots in-repo
|
||||
- [ ] Add focused tests for low-risk utilities:
|
||||
- [x] مقياس التغطية بحيث يعكس اللون الأفضل من ملفات الاختبار
|
||||
- [x] تستخدم بنص التغطية القديم للمقارنة
|
||||
- [x] قام بعدم وجود خط الأساس ونقاط الاتصال في الريبو
|
||||
- [ ] إضافة السيولة المركزية للمرافق المتعددة:
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/fetchTimeout.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/display/names.ts`
|
||||
- [ ] Add route tests for:
|
||||
- [ ] إضافة السيولة لـ:
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`### المرحلة الثانية: 60% -> 65%
|
||||
|
||||
### Phase 2: 60% -> 65%
|
||||
|
||||
- [ ] Add DB-backed tests for:
|
||||
- [ ] إضافة السيولة المدعومة بقاعدة البيانات لـ:
|
||||
- `src/lib/db/modelComboMappings.ts`
|
||||
- `src/lib/db/settings.ts`
|
||||
- `src/lib/db/registeredKeys.ts`
|
||||
- [ ] Cover branch behavior in:
|
||||
- [ ] اشتباكات الفرع في:
|
||||
- `src/lib/providers/validation.ts`
|
||||
- `src/app/api/v1/embeddings/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`### المرحلة الثالثة: 65% -> 70%
|
||||
|
||||
### Phase 3: 65% -> 70%
|
||||
|
||||
- [ ] Add usage analytics tests for:
|
||||
- [ ] إضافة السيولة تحليلات الاستخدام لـ:
|
||||
- `src/lib/usage/usageHistory.ts`
|
||||
- `src/lib/usage/usageStats.ts`
|
||||
- `src/lib/usage/costCalculator.ts`
|
||||
- [ ] Expand route coverage for proxy management and settings branches
|
||||
- [ ] التغطية المكثفة للمحتوى الإبداعي متنوع ### المرحلة 4: 70% -> 75%
|
||||
|
||||
### Phase 4: 70% -> 75%
|
||||
|
||||
- [ ] Cover translator helpers and central translation paths:
|
||||
- [ ] تغطية مساعدي المترجم ومسارات الترجمة المركزية:
|
||||
- `open-sse/translator/index.ts`
|
||||
- `open-sse/translator/helpers/*`
|
||||
- `open-sse/translator/request/*`
|
||||
- `open-sse/translator/response/*`
|
||||
- `open-sse/translator/response/*`### المرحلة الخامسة: 75% -> 80%
|
||||
|
||||
### Phase 5: 75% -> 80%
|
||||
|
||||
- [ ] Add handler-level tests for:
|
||||
- [ ] إضافة السيولة على مستوى رام لـ:
|
||||
- `open-sse/handlers/chatCore.ts`
|
||||
- `open-sse/handlers/responsesHandler.js`
|
||||
- `open-sse/handlers/imageGeneration.js`
|
||||
- `open-sse/handlers/embeddings.js`
|
||||
- [ ] Add executor branch coverage for provider-specific auth, retries, and endpoint overrides
|
||||
- [ ] إضافة المنفذ الفرعي للمصادقة الخاصة بالموفر، لتقديم المحاولة، وتجاوزات نقطة النهاية### المرحلة 6: 80% -> 85%
|
||||
|
||||
### Phase 6: 80% -> 85%
|
||||
- [ ] دمج المزيد من مجموعات الأحداث المتقدمة في مسار التغطية الرئيسية
|
||||
- [ ] الزيادة الوظيفية للوحدات قاعدة البيانات ذات التغطية الضعيفة للمنشئ/المساعد
|
||||
- [ ] إغلاق فجوات الفروع في "settings.ts"، و"registeredKeys.ts"، و"validation.ts"، ومساعدي المترجم### المرحلة السابعة: 85% -> 90%
|
||||
|
||||
- [ ] Merge more edge-case suites into the main coverage path
|
||||
- [ ] Increase function coverage for DB modules with weak constructor/helper coverage
|
||||
- [ ] Close branch gaps in `settings.ts`, `registeredKeys.ts`, `validation.ts`, and translator helpers
|
||||
- [ ] بعض القضايا ذات الميزانية المحدودة المتبقية على أدوات الحظر
|
||||
- [ ] إضافة نسبة الانحدار لكل خطأ إنتاجي تم اكتشافه وإصلاحه أثناء الدفع إلى 90%
|
||||
- [ ] رفع بوابة التغطية في CI فقط بعد أن يكون الخط المحلي الأساسي قائمًا لتشغيلتين متتاليتين على الأقل## Ratchet Policy
|
||||
|
||||
### Phase 7: 85% -> 90%
|
||||
قم بالتأكيد بعتبات تشغيل npm: التغطية فقط بعد التجاوز الفعلي فعليًا، المرحلة الرئيسية التالية في مخزن الراحة.
|
||||
|
||||
- [ ] Treat the remaining low-coverage files as blockers
|
||||
- [ ] Add regression tests for every uncovered production bug fixed during the push to 90%
|
||||
- [ ] Raise the coverage gate in CI only after the local baseline is stable for at least two consecutive runs
|
||||
|
||||
## Ratchet policy
|
||||
|
||||
Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
|
||||
|
||||
Recommended ratchet sequence:
|
||||
سلسلة السقاطة لسبب:
|
||||
|
||||
1. 55/60/55
|
||||
2. 60/62/58
|
||||
@@ -163,8 +132,6 @@ Recommended ratchet sequence:
|
||||
7. 85/80/84
|
||||
8. 90/85/88
|
||||
|
||||
Order is `statements-lines / branches / functions`.
|
||||
الترتيب هو "أسطر البيانات / الفروع / الوظائف".## الثغرة المعروفة
|
||||
|
||||
## Known gap
|
||||
|
||||
The current coverage command measures the main Node unit suite and includes source reached from it, including `open-sse`. It does not yet merge Vitest coverage into a single unified report. That merge is worth doing later, but it is not a blocker for starting the 60% -> 80% climb.
|
||||
يقيس أمر التغطية الحالية لمجموعة العقد الرئيسية بمشاركة المصدر الذي يتم الوصول إليه منه، بما في ذلك `open-sse`. لم أدمج بعد تغطية Vitest في التقرير الموحد الواحد. وقد تم إنجاز هذا لاحقًا، ولكن لا تزيد سرعة زيادة الذاكرة بنسبة 60% -> 80%.
|
||||
|
||||
@@ -1,145 +1,73 @@
|
||||
# OmniRoute — Dashboard Features Gallery (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [hi](../../hi/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md) · 🇹🇷 [tr](../../tr/docs/FEATURES.md)
|
||||
|
||||
---
|
||||
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
دليل مرئي لكل قسم من معلومات لوحة OmniRoute.---## 🔌 Providers
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (Qoder, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

|
||||
|
||||
---
|
||||
إدارة اتصالات الذكاء الصناعي: موفري OAuth (Claude Code وCodex وGemini CLI) وموفري مفاتيح API (Groq وDeepSeek وOpenRouter) ومقدمي خدمات العيد (Qoder وQwen وKiro). لحسابات كيرو على تتبع الاعتماد الائتماني - الأرصدة النهائية لإجمالي استطلاعات الرأي المتخصصة في لوحة التحكم → استخدام.---
|
||||
|
||||
## 🎨 Combos
|
||||
|
||||
Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
|
||||
|
||||

|
||||
|
||||
---
|
||||
أنشئ مجموعات التوجيه باستخدام 6 إستراتيجيات: نأمل، والمتزايدة، والدورية، والعشوائية، وأقل استخدامًا، والمُحسّن من حيث التكلفة. وخاصة مجموعة نماذج متعددة مع اختلافات سريعة وفحوصات للجاهزية.---
|
||||
|
||||
## 📊 Analytics
|
||||
|
||||
Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
|
||||
|
||||

|
||||
|
||||
---
|
||||
تحليلات استخدام شاملة مع الرمز المميز، وتقديرات التكلفة، وخرائط، ومخططات التوزيع الأسبوعية، والتفاصيل لكل محمية.---
|
||||
|
||||
## 🏥 System Health
|
||||
|
||||
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states.
|
||||
|
||||

|
||||
|
||||
---
|
||||
التسجيل في الوقت الفعلي: وقت العمل، والذاكرة، والإصدار، والنسب لزمن الوصول (p50/p95/p99)، وإحصائيات ذاكرة التخزين المؤقتة، وحالات منع دائرة الموفر.---
|
||||
|
||||
## 🔧 Translator Playground
|
||||
|
||||
Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream).
|
||||
|
||||

|
||||
|
||||
---
|
||||
أدوات لتصحيح أخطاء ترجمات برمجة التطبيقات:**ساحة اللعب**(محول أربعة نجاح)،**اختبار الدردشة**(الطلب المباشر)،**منصة الاختبار**(اختبارات الدفعة)، و**المراقب المباشر**(بث الوقت في العمل).---
|
||||
|
||||
## 🎮 Model Playground _(v2.0.9+)_
|
||||
|
||||
Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics.
|
||||
اختبر أي نموذج مباشرة من لوحة القيادة. حدد الموفر والطراز والنقطة النهائية، وكتب المطالبات باستخدام محرر موناكو، وقم بتفعيل الاستثناءات في المنتج الفعلي، وإلغاء منتصف الدفق، والمعايرة التقليدية مرة.---## 🎨 Themes _(v2.0.5+)_
|
||||
|
||||
---
|
||||
ألوان قابلة للتخصيص لمعلومات لوحة المفاتيح بأكملها. اختر من بين 7 ألوان محددة ليمين (مرجاني، أزرق، أخضر، بنفسجي، لون أحمر، سماوي) أو قم باختيار سمة مخصصة عن طريق اختيار أي سداسي عشري. يدعم وضع الضوء والظلام النظام.---## ⚙️ Settings
|
||||
|
||||
## 🎨 Themes _(v2.0.5+)_
|
||||
لوحة الإعدادات شاملة مع علامات التبويب:
|
||||
|
||||
Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Settings
|
||||
|
||||
Comprehensive settings panel with tabs:
|
||||
|
||||
- **General** — System storage, backup management (export/import database)
|
||||
- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning, auto-disable banned accounts, provider expiration monitoring
|
||||
- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode
|
||||
|
||||

|
||||
|
||||
---
|
||||
-**عام**— تخزين النظام، وإدارة النسخ الاحتياطي (قاعدة بيانات التصدير/الاستيراد) -**المظهر**— محدد السماعة (داكن/فاتح/نظام)، الإعدادات المسبقة لموضوع الألوان والألوان المخصصة، ورؤية السجل الصحي، وعناصر التحكم في رؤية عنصر الشريط الجانبي -**الأمان**— حماية نقطة نهاية واجهة برمجة التطبيقات، وحظر الموفر المخصص، وتصفية IP، ومعلومات الاتصال -**التوجيه**— الأسماء المستعارة للنماذج، و الابتكارات الخلفية -**المرونة**— ونتيجة لذلك الحد الأقصى للمعدل، وضبط القيود، والتعطيل التلقائي للحسابات المحظورة، وانتهاء صلاحية الموفر -**متقدم**— تجاوز، ومسار تدقيق فقط، وتطبيق التدمير الاحتياطي---
|
||||
|
||||
## 🔧 CLI Tools
|
||||
|
||||
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping.
|
||||
|
||||

|
||||
|
||||
---
|
||||
ختمة واحدة لأدوات تميز الذكاء الصناعي: Claude Code، وCodex CLI، وGemini CLI، وOpenClaw، وKilo Code، وAntigravity، وCline، وContinue، وCursor، وFactory Droid. تم تفعيل/إعادة ضبط تلقائي، فقط تعريف الاتصال، والنتائج المباشرة.---
|
||||
|
||||
## 🤖 CLI Agents _(v2.0.11+)_
|
||||
|
||||
Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with:
|
||||
لوحة معلومات للتحكم في وكلاء CLI. تم عرض شبكة مكونة من 14 وكيلًا مدمجًا (Codex وClaude وGoose وGemini CLI وOpenClaw وAider وOpenCode وCline وQwen Code وForgeCode وAmazon Q وOpen Interpreter وCursor CLI وWarp) مع:
|
||||
|
||||
- **Installation status** — Installed / Not Found with version detection
|
||||
- **Protocol badges** — stdio, HTTP, etc.
|
||||
- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args)
|
||||
- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP
|
||||
-**حالة التثبيت**— تم التثبيت/لم يتم العثور عليه باستخدام اكتشاف الإصدار -**توصيات المذكورة**— stdio، HTTP، وما إلى ذلك. -**الوكلاء يستهدفون**— هل هناك أي أداة لواجهة سطر الوكيل (CLI) عبر النموذج (الاسم، ثنائي، أمر الإصدار، وسيط النشر) -**مطابقة بصمة CLI**— التبديل لكل المرشحين لمطابقة توقيعات طلب CLI الأصلية، مما سيقدر من المبدع بالفعل مع ضمان عنوان IP الوكيل---## 🖼️ Media _(v2.0.3+)_
|
||||
|
||||
---
|
||||
موجود في الصور ومقاطع الفيديو والموسيقى من لوحة التحكم. يدعم OpenAI وxAI وTogether وHyperbolic وSD WebUI وComfyUI وAnimateDiff وStable Audio Open وMusicGen.---## 📝 Request Logs
|
||||
|
||||
## 🖼️ Media _(v2.0.3+)_
|
||||
|
||||
Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Request Logs
|
||||
|
||||
Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details.
|
||||
|
||||

|
||||
|
||||
---
|
||||
تسجيل طلبات الإنتاج في الواقع باستخدام التصفية حسب الموفر والطراز والحساب ومفتاح واجهة برمجة التطبيقات. معلمات القيمة الناتجة عن التعويض الطبيعي ووقت التعويض وتفاصيل التعويض.---
|
||||
|
||||
## 🌐 API Endpoint
|
||||
|
||||
Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloudflare Quick Tunnel integration and cloud proxy support for remote access.
|
||||
|
||||

|
||||
|
||||
---
|
||||
نقطة نهاية واجهة برمجة التطبيقات الموحدة الخاصة بك مع تفاصيل التفاصيل: عمليات التسجيل، وواجهة برمجة تطبيقات الاستجابات، والتضمينات، وأي الصور، إلى الإعداد، والنسخة الصوتية، تحويل النص إلى كلام، والإشراف، ومفاتيح واجهة برمجة التطبيقات المفقودة. تكامل Cloudflare Quick Tunnel للتواصل مع وكيل السحابي للوصول إليه بعد.---
|
||||
|
||||
## 🔑 API Key Management
|
||||
|
||||
Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking.
|
||||
إنشاء مفاتيح API ونطاقها لربط وإلها. يمكن أن يكون هناك كل المفاتيح الرئيسية على/موفري خدمات محددة لهم حق الوصول الكامل أو أذونات القراءة فقط. إدارة المفاتيح المرئية مع تكرار الاستخدام.---## 📋 Audit Log
|
||||
|
||||
---
|
||||
متابعة الإجراءات الإدارية بالتصفية حسب نوع الإجراء والممثل والهدف وعنوان IP والطابع الزمني. سجل الأحداث الأمنية الكاملة.---## 🖥️ Desktop Application
|
||||
|
||||
## 📋 Audit Log
|
||||
تطبيق Native Electron لسطح المكتب لأنظمة التشغيل Windows وmacOS وLinux. قم بالموافقة على OmniRoute كتطبيق مستقل مع نظام متكامل للنظام والدعم دون الاتصال والتحديث التلقائي والتثبيت بنقرة واحدة.
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
الميزات الرئيسية:
|
||||
|
||||
---
|
||||
- استقصاء جاهزية الضيوف (لا توجد شاشة عند التشغيل البارد)
|
||||
- نظام إدارة المنافذ
|
||||
- اتخاذ القرار بشأن المحتوى
|
||||
- مثال واحد
|
||||
- التحديث التلقائي عند إعادة التشغيل
|
||||
- واجهة المستخدم مشروطة بالكامل (إشارات المرور لنظام التشغيل MacOS، وشريط العنوان الإلكتروني لنظام التشغيل Windows/Linux)
|
||||
- بناء الإلكترون المقوى - يتم إبتكار "وحدات_العقدة" وتشهد بالرمز في المقترحات ورفضها قبل قبولها، مما يمنع الاعتماد في وقت التشغيل على البناء (الإصدار 2.5.5+)
|
||||
|
||||
## 🖥️ Desktop Application
|
||||
|
||||
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, 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
|
||||
- Auto-update on restart
|
||||
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
|
||||
- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+)
|
||||
|
||||
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
|
||||
📖 راجع [`electron/README.md`](../electron/README.md) للحصول على التوثيق الكامل.
|
||||
|
||||
356
docs/i18n/ar/docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
356
docs/i18n/ar/docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,356 @@
|
||||
# OmniRoute Fly.io 部署指南 (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/FLY_IO_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
تم إنشاء OmniRoute في Fly.io من خلال الرابط التالي:
|
||||
|
||||
- تم تطويره بواسطة Fly.io
|
||||
- 后续代码更新后继续发布
|
||||
- 新项目参考同样流程部署
|
||||
|
||||
من المحتمل أن هذا هو السبب في أن كل ما عليك فعله هو ` Omniroute`.---## 1. 部署目标
|
||||
|
||||
- الاسم: Fly.io
|
||||
- 部署方式: تم إنشاء `flyctl` 直接接发布
|
||||
- قم بتنزيل الرابط: قم بتنزيل الملف `Dockerfile` و`fly.toml`.
|
||||
- الاسم الأصلي: Fly Volume موجود في `/data`
|
||||
- الرابط:`https://omniroute.fly.dev/`---## 2. 当前项目关键配置
|
||||
|
||||
قم بزيارة الرابط التالي `fly.toml` من خلال الرابط التالي:```toml
|
||||
التطبيق = "الطريق الشامل"
|
||||
Primary_region = 'الخطيئة'
|
||||
|
||||
[[يتصاعد]]
|
||||
المصدر = "البيانات"
|
||||
الوجهة = '/ البيانات'
|
||||
|
||||
[العمليات]
|
||||
التطبيق = 'عقدة تشغيل Standalone.mjs'
|
||||
|
||||
[http_service]
|
||||
منفذ داخلي = 20128
|
||||
|
||||
[بيئة]
|
||||
TZ = "آسيا/شنغهاي"
|
||||
المضيف = "0.0.0.0"
|
||||
اسم المضيف = "0.0.0.0"
|
||||
ربط = "0.0.0.0"```
|
||||
|
||||
الاسم:
|
||||
|
||||
- `app = 'omniroute'' تطبيق Fly 应用
|
||||
- `الوجهة = '/ البيانات''
|
||||
- قم بإلغاء تحديد `DATA_DIR=/data`، وقم بإلغاء تحديد موقع الويب الخاص بك---
|
||||
|
||||
## 3. 必备工具
|
||||
|
||||
### 3.1 安装 Fly CLI
|
||||
|
||||
ويندوز بوويرشيل:```powershell
|
||||
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
|
||||
|
||||
````
|
||||
|
||||
يمكن أن يكون هذا هو الحال بالنسبة لـ "flyctl" أو "PATH" أو "PATH".### 3.2 登录 Fly 账号```powershell
|
||||
flyctl auth login
|
||||
````
|
||||
|
||||
### 3.3 检查登录状态
|
||||
|
||||
```powershell
|
||||
flyctl auth whoami
|
||||
flyctl version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 首次部署当前项目
|
||||
|
||||
### 4.1 获取代码并进入目录
|
||||
|
||||
```powershell
|
||||
git clone https://github.com/xiaoge1688/OmniRoute.git
|
||||
cd OmniRoute
|
||||
```
|
||||
|
||||
### 4.2 确认应用名
|
||||
|
||||
قم بزيارة `fly.toml`، باستخدام الرابط التالي:`toml
|
||||
التطبيق = "الطريق الشامل"`
|
||||
|
||||
يجب أن تكون قادرًا على التعامل مع هذه المشكلة على النحو التالي:```toml
|
||||
app = 'omniroute-yourname'
|
||||
|
||||
````
|
||||
|
||||
الاسم:
|
||||
|
||||
- قم بالنقر على زر "fly.toml" من خلال "التطبيق" الموجود على الرابط
|
||||
- 以前如果用过别的名字، 例如 `الطريق`، 不要 و``الطريق الشامل` 混淆### 4.3 创建应用
|
||||
|
||||
اسم المنتج:```powershell
|
||||
تقوم تطبيقات flyctl بإنشاء طريق شامل```
|
||||
|
||||
من المؤكد أن هذا يعني أن "الطريق الشامل" هو الطريق الصحيح.### 4.4 首次部署
|
||||
|
||||
```powershell
|
||||
نشر flyctl```
|
||||
|
||||
---
|
||||
|
||||
## 5. 必配参数
|
||||
|
||||
تم إطلاق لعبة Fly.io على جهاز الكمبيوتر الخاص بك.### 5.1 已验证使用的参数
|
||||
|
||||
أفضل الطرق للوصول إلى الطريق الشامل هي:
|
||||
|
||||
- `API_KEY_SECRET`
|
||||
- `DATA_DIR`
|
||||
- `JWT_SECRET`
|
||||
- `MACHINE_ID_SALT`
|
||||
- `NEXT_PUBLIC_BASE_URL`
|
||||
- `STORAGE_ENCRYPTION_KEY`### 5.2 关于 `INITIAL_PASSWORD`
|
||||
|
||||
اختر كلمة مرور `INITIAL_PASSWORD`، وقم بإلغاء تحديدها.
|
||||
|
||||
العنوان:
|
||||
|
||||
- 启动日志会提示默认密码是 `CHANGEME'
|
||||
- ماكينات غسيل الملابس
|
||||
|
||||
يجب أن تكون قادرًا على التعامل مع هذه المشكلة:
|
||||
|
||||
- `INITIAL_PASSWORD`---
|
||||
|
||||
## 6. 推荐参数说明
|
||||
|
||||
### 6.1 Secrets 中设置
|
||||
|
||||
أسرار الطيران:
|
||||
|
||||
| 变量名 | 是否推荐 | 说明 |
|
||||
| ------------------------ | -------- | ------------------------------ |
|
||||
| `API_KEY_SECRET` | 必需 | مفتاح API 生成与校验使用 |
|
||||
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
|
||||
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
|
||||
| `MACHINE_ID_SALT` | جديد | 生成稳定机器标识 |
|
||||
| `INITIAL_PASSWORD` | 可选 | ماكينات غسيل الملابس في الصين |
|
||||
| OAuth/API 私密凭证 | الصفحة الرئيسية | 各类外部平台鉴权配置 |### 6.2 当前项目推荐值
|
||||
|
||||
| 变量名 | جديد |
|
||||
| ---------------------- | --------------------------- |
|
||||
| `DATA_DIR` | `/ البيانات` |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
|
||||
|
||||
الاسم:
|
||||
|
||||
- `DATA_DIR=/data` 非常关键،تحديد حجم الطيران
|
||||
- `NEXT_PUBLIC_BASE_URL' عنوان البريد الإلكتروني الخاص بنا---
|
||||
|
||||
## 7. 一键设置参数
|
||||
|
||||
تم إنشاء هذا الرابط من قبل شركة Fly Secrets.
|
||||
|
||||
الاسم:
|
||||
|
||||
- اختر "INITIAL_PASSWORD".
|
||||
- 适用于当前项目 "شامل"```powershell
|
||||
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
|
||||
flyctl secrets set `
|
||||
API_KEY_SECRET=$apiKeySecret `
|
||||
JWT_SECRET=$jwtSecret `
|
||||
MACHINE_ID_SALT=$machineIdSalt `
|
||||
STORAGE_ENCRYPTION_KEY=$storageKey `
|
||||
DATA_DIR=/data `
|
||||
NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev `
|
||||
-a omniroute
|
||||
````
|
||||
|
||||
ما هي أفضل الطرق التي يجب اتباعها:`powershell
|
||||
مجموعة أسرار flyctl INITIAL_PASSWORD=你的强密码 - طريق شامل`
|
||||
|
||||
---
|
||||
|
||||
## 8. 查看当前参数
|
||||
|
||||
````powershell
|
||||
قائمة أسرار flyctl - طريق شامل```
|
||||
|
||||
如果控制台 ``الأسرار`` 页面没有显示你期待的变量،先检查:
|
||||
|
||||
- omniroute omniroute
|
||||
- `fly.toml' 的 `app` 是否和控制台应用一致---
|
||||
|
||||
## 9. 后续更新发布
|
||||
|
||||
أفضل ما في الأمر:```powershell
|
||||
git pull
|
||||
flyctl deploy
|
||||
````
|
||||
|
||||
أفضل ما في الأمر:`powershell
|
||||
تعيين أسرار flyctl KEY=value -a omniroute`
|
||||
|
||||
يطير هنا.### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
|
||||
|
||||
شوكة 如果当前仓库是، 并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute` 的更新، 推荐按下面流程执行.
|
||||
|
||||
العنوان:```powershell
|
||||
git remote -v
|
||||
|
||||
````
|
||||
|
||||
اسم المنتج:
|
||||
|
||||
- "الأصل" 指向你自己的
|
||||
- `المنبع` 指向原仓库
|
||||
|
||||
المنبع ``المنبع``:```powershell
|
||||
git عن بعد إضافة المنبع https://github.com/diegosouzapw/OmniRoute.git```
|
||||
|
||||
أفضل ما في الأمر:```powershell
|
||||
git fetch upstream --tags
|
||||
````
|
||||
|
||||
أفضل ما في الأمر:`powershell
|
||||
وصف git --tags --دائما
|
||||
عرض git --no-patch --oneline v3.4.7`
|
||||
|
||||
如果你想合并上游最新 `main`، 并强制保留 fork 当前的 `fly.toml`، 可按下面流程执行:```powershell
|
||||
git merge upstream/main
|
||||
git checkout HEAD~1 -- fly.toml
|
||||
git add -- fly.toml
|
||||
git commit -m "chore(deploy): keep fork fly.toml"
|
||||
git push origin main
|
||||
|
||||
````
|
||||
|
||||
الاسم:
|
||||
|
||||
- ``دمج بوابة المنبع/الرئيسية''
|
||||
- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
|
||||
- 如果上游没有改 `fly.toml`، 这一步不会带来额外差异
|
||||
- اضغط على `fly.toml`، واستخدام حماية Fly لملفات تعريف الارتباط، والملفات، وشوكة شوكة.
|
||||
|
||||
تم إنشاء الإصدار 3.4.7 من الإصدار 3.4.7، وقد تم تصميمه بواسطة ``المنبع/الرئيسي``:```powershell
|
||||
git merge-base --is-ancestor v3.4.7 upstream/main```
|
||||
|
||||
يتم تحديد المنبع/الرئيسي بواسطة المنبع/الرئيسي.### 9.2 同步上游后的标准发布顺序
|
||||
|
||||
أفضل ما في الأمر هو الحصول على أفضل الأسعار:
|
||||
|
||||
1. جلب git المنبع --tags
|
||||
2. "دمج بوابة المنبع/الرئيسية".
|
||||
3. شوكة شوكة "fly.toml".
|
||||
4. `جيت دفع الأصل الرئيسي`
|
||||
5. "نشر flyctl".
|
||||
6. ``حالة flyctl - طريق شامل``
|
||||
7. ``flyctl logs --no-tail -a omniroute`
|
||||
|
||||
تم تحديث الإصدار `v3.4.7` من الإصدار الجديد.---
|
||||
|
||||
## 10. 发布后检查
|
||||
|
||||
### 10.1 查看应用状态
|
||||
|
||||
```powershell
|
||||
حالة flyctl - طريق شامل```
|
||||
|
||||
### 10.2 查看启动日志
|
||||
|
||||
```powershell
|
||||
سجلات flyctl - بدون ذيل - طريق شامل```
|
||||
|
||||
### 10.3 检查网站可访问
|
||||
|
||||
```powershell
|
||||
حاول {
|
||||
(استدعاء WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).رمز الحالة
|
||||
} أمسك {
|
||||
إذا ($_.Exception.Response) {
|
||||
$_.Exception.Response.StatusCode.value__
|
||||
} آخر {
|
||||
رمي
|
||||
}
|
||||
}```
|
||||
|
||||
`200` 说明站点已正常响应.---
|
||||
|
||||
## 11. 成功标志
|
||||
|
||||
أفضل ما في الأمر:```text
|
||||
[bootstrap] Secrets persisted to: /data/server.env
|
||||
[DB] SQLite database ready: /data/storage.sqlite
|
||||
````
|
||||
|
||||
هذا هو الحل:
|
||||
|
||||
- `/data/server.env`
|
||||
- `/data/storage.sqlite` تم تخزين البيانات فيه
|
||||
|
||||
تم إلغاء الطلب `/app/data/...`، ``DATA_DIR` إلغاء الطلب، 需要立即修正.---## 12. 常见问题
|
||||
|
||||
### 12.1 `Secrets` 页面是空的
|
||||
|
||||
اسم المنتج:
|
||||
|
||||
- 你还没执行 "مجموعة أسرار flyctl".
|
||||
- تم إلغاء التثبيت، `الطريق`، `الطريق الشامل`### 12.2 `flyctlploy` `لم يتم العثور على التطبيق`
|
||||
|
||||
اسم المنتج:`powershell
|
||||
تقوم تطبيقات flyctl بإنشاء طريق شامل`
|
||||
|
||||
### 12.3 `fly.toml` 解析失败
|
||||
|
||||
اسم المنتج:
|
||||
|
||||
- 注释里是否有乱码字符
|
||||
- TOML 引号和缩进是否正确### 12.4 数据没有持久化
|
||||
|
||||
检查以下两点:
|
||||
|
||||
- `fly.toml` `الوجهة = '/ البيانات''
|
||||
- `DATA_DIR` 是否设置为 `/data`### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
|
||||
|
||||
هذا هو السبب في أن هذا هو السبب وراء `CHANGEME`.---
|
||||
|
||||
## 13. 新项目复用建议
|
||||
|
||||
لا داعي للقلق بشأن هذه المشكلة:
|
||||
|
||||
1. قم بتنزيل "fly.toml" على "التطبيق"
|
||||
2. قم بزيارة `NEXT_PUBLIC_BASE_URL`
|
||||
3. اختر "DATA_DIR=/data".
|
||||
4. قم بالضغط على `API_KEY_SECRET`、`JWT_SECRET`、`MACHINE_ID_SALT`、`STORAGE_ENCRYPTION_KEY`
|
||||
5. قم بإنشاء بيانات جديدة `/data`
|
||||
|
||||
لا داعي للقلق بشأن هذا الأمر.---
|
||||
|
||||
## 14. 当前项目的最小发布清单
|
||||
|
||||
أفضل ما في الأمر هو الحصول على أفضل النتائج:```powershell
|
||||
flyctl auth whoami
|
||||
flyctl status -a omniroute
|
||||
flyctl secrets list -a omniroute
|
||||
flyctl deploy
|
||||
flyctl logs --no-tail -a omniroute
|
||||
|
||||
````
|
||||
|
||||
أفضل ما في الأمر:```powershell
|
||||
نشر flyctl```
|
||||
|
||||
أفضل ما في الأمر:
|
||||
|
||||
1. "تسجيل الدخول بمصادقة flyctl".
|
||||
2. `تطبيقات flyctl تنشئ طريقًا شاملاً`
|
||||
3. ``مجموعة أسرار flyctl ... -طريق شامل``
|
||||
4. "نشر flyctl".
|
||||
5. `سجلات flyctl --no-tail -a omniroute`
|
||||
````
|
||||
361
docs/i18n/ar/docs/I18N.md
Normal file
361
docs/i18n/ar/docs/I18N.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# i18n — Internationalization Guide (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/I18N.md) · 🇪🇸 [es](../../es/docs/I18N.md) · 🇫🇷 [fr](../../fr/docs/I18N.md) · 🇩🇪 [de](../../de/docs/I18N.md) · 🇮🇹 [it](../../it/docs/I18N.md) · 🇷🇺 [ru](../../ru/docs/I18N.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/I18N.md) · 🇯🇵 [ja](../../ja/docs/I18N.md) · 🇰🇷 [ko](../../ko/docs/I18N.md) · 🇸🇦 [ar](../../ar/docs/I18N.md) · 🇮🇳 [hi](../../hi/docs/I18N.md) · 🇮🇳 [in](../../in/docs/I18N.md) · 🇹🇭 [th](../../th/docs/I18N.md) · 🇻🇳 [vi](../../vi/docs/I18N.md) · 🇮🇩 [id](../../id/docs/I18N.md) · 🇲🇾 [ms](../../ms/docs/I18N.md) · 🇳🇱 [nl](../../nl/docs/I18N.md) · 🇵🇱 [pl](../../pl/docs/I18N.md) · 🇸🇪 [sv](../../sv/docs/I18N.md) · 🇳🇴 [no](../../no/docs/I18N.md) · 🇩🇰 [da](../../da/docs/I18N.md) · 🇫🇮 [fi](../../fi/docs/I18N.md) · 🇵🇹 [pt](../../pt/docs/I18N.md) · 🇷🇴 [ro](../../ro/docs/I18N.md) · 🇭🇺 [hu](../../hu/docs/I18N.md) · 🇧🇬 [bg](../../bg/docs/I18N.md) · 🇸🇰 [sk](../../sk/docs/I18N.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/I18N.md) · 🇮🇱 [he](../../he/docs/I18N.md) · 🇵🇭 [phi](../../phi/docs/I18N.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/I18N.md) · 🇨🇿 [cs](../../cs/docs/I18N.md) · 🇹🇷 [tr](../../tr/docs/I18N.md)
|
||||
|
||||
---
|
||||
|
||||
يدعم OmniRoute**30 لغة**مع ترجمة كاملة لواجهة مستخدم لوحة المعلومات، والوثائق المترجمة، ودعم RTL للغة العربية والعبرية.## مرجع سريع
|
||||
|
||||
| مهمة | الأمر |
|
||||
| ------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------- |
|
||||
| توليد الترجمات | `نصوص المؤتمرة/i18n/generate-multilang.mjs messages` |
|
||||
| ترجمة المستندات (ماجستير في القانون) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <key> --model <model>` |
|
||||
| التحقق من صحة اللغة | `python3 scripts/validate_translation.py fast -l cs` |
|
||||
| تحقق من المفاتيح التعليمات | `python3 scripts/check_translations.py` |
|
||||
| إنشاء تقرير ضمان الجودة | `العقدة النصية/i18n/generate-qa-checklist.mjs` |
|
||||
| ضمان الجودة المرئية (كاتب مسرحي) | `العقدة النصية/i18n/run-visual-qa.mjs` | ##الهندسة### Source of Truth |
|
||||
|
||||
-**سلاسل واجهة المستخدم**: `src/i18n/messages/en.json` (المصدر باللغة الإنجليزية، ~2800 مفتاح) -**ملفات اللغة**: `src/i18n/messages/{locale}.json` (30 ترجمة) -**Framework**: `next-intl` مع الاعتماد التلقائي المستندة إلى ملفات تعريف الارتباط -**التكوين**: `src/i18n/config.ts` — يحدد جميع اللغات الثلاثين وأسماء اللغات والأعلام### Runtime Flow
|
||||
|
||||
1. يقوم المستخدم باختيار اللغة → مجموعة ملفات تعريف الارتباط `NEXT_LOCALE`
|
||||
2. `src/i18n/request.ts` يحل اللغة: ملف تعريف الارتباط → رأس `قبول اللغة` → محايد `ar`
|
||||
3. يقوم باستيراد الرسائل الالكترونية/{locale}.json
|
||||
4.استخدام المكونات `useTranslations("namespace")` و`t("key")`### اللغات المدعومة
|
||||
|
||||
| الكود | اللغة | من الإنجليزية إلى فارس | كود ترجمة جوجل |
|
||||
| -------------------- | --------------------- | ---------------------- | ----------------- | -------------------------------------------- |
|
||||
| `ع` | العربية | نعم | `ع` |
|
||||
| `بج` | البلغارية | لا | `بج` |
|
||||
| `CS` | تشيستينا | لا | `CS` |
|
||||
| `دا` | دانسك | لا | `دا` |
|
||||
| `دي` | الألمانية | لا | `دي` |
|
||||
| `es` | الاسبانية | لا | `es` |
|
||||
| `في` | سومي | لا | `في` |
|
||||
| `الاب` | الفرنسية | لا | `الاب` |
|
||||
| `هو` | عبرية | نعم | `iw` |
|
||||
| `مرحبا` | الهندية | لا | `مرحبا` |
|
||||
| `هو` | المجرية | لا | `هو` |
|
||||
| "معرف" | البهاسا الإندونيسية | لا | "معرف" |
|
||||
| "إنه" | إيطالينو | لا | "إنه" |
|
||||
| `جا` | 日本語 | لا | `جا` |
|
||||
| `كو` | 한국어 | لا | `كو` |
|
||||
| `مس` | البهاسا ملايو | لا | `مس` |
|
||||
| `نل` | هولندا | لا | `نل` |
|
||||
| `لا` | نورسك | لا | `لا` |
|
||||
| `فاي` | فلبينية | لا | `ل` |
|
||||
| `ر` | بولسكي | لا | `ر` |
|
||||
| `نقطة` | البرتغالية (البرتغال) | لا | `نقطة` |
|
||||
| `pt-BR` | إسبانيا (البرازيل) | لا | `نقطة` |
|
||||
| `رو` | رومانا | لا | `رو` |
|
||||
| `رو` | Русский | لا | `رو` |
|
||||
| `سك` | سلوفينيا | لا | `سك` |
|
||||
| `sv` | سفينسكا | لا | `sv` |
|
||||
| `ال` | ไทย | لا | `ال` |
|
||||
| `تر` | تركي | لا | `تر` |
|
||||
| `المملكة المتحدة-UA` | أوكرانيا | لا | `المملكة المتحدة` |
|
||||
| `السادس` | تينغ فيت | لا | `السادس` |
|
||||
| `zh-CN` | 中文 (简体) | لا | `zh-CN` | ## إضافة لغة جديدة### 1. Register the Locale |
|
||||
|
||||
تحرير `src/i18n/config.ts`:`ts
|
||||
// أضف إلى مجموعة LOCALES
|
||||
"س س"،
|
||||
// أضف إلى مصفوفة اللغات
|
||||
{ الكود: "xx"، التصنيف: "XX"، الاسم: "اسم اللغة"، العلم: "🏳️" },`
|
||||
|
||||
### 2. Add to Generator
|
||||
|
||||
تحرير "scripts/i18n/generate-multilang.mjs" - إضافة إدخال إلى "LOCALE_SPECS":```js
|
||||
{
|
||||
code: "xx",
|
||||
googleTl: "xx",
|
||||
label: "XX",
|
||||
flag: "🏳️",
|
||||
languageName: "Language Name",
|
||||
readmeName: "Language Name",
|
||||
docsName: "Language Name",
|
||||
},
|
||||
|
||||
````
|
||||
|
||||
### 3. Generate Initial Translation
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs messages
|
||||
````
|
||||
|
||||
يؤدي هذا إلى إنشاء src/i18n/messages/xx.json مترجمًا آليًا من `en.json` عبر الترجمة خدمة من Google.### 4. مراجعة الترجمات التلقائية وإصلاحها
|
||||
|
||||
الترجمات التلقائية هي نقطة البداية. التعديل اليدوي لـ:
|
||||
|
||||
- الدقة الفنية
|
||||
- المصطلحات الصحيحة للسياق
|
||||
- التعامل مع العناصر النائبة (`{count}`، `{value}`، وما إلى ذلك)### 5. التحقق من صحة```bash
|
||||
python3 scripts/validate_translation.py quick -l xx
|
||||
python3 scripts/validate_translation.py diff common -l xx
|
||||
|
||||
````
|
||||
|
||||
### 6. Generate Translated Documentation
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs docs
|
||||
````
|
||||
|
||||
## Auto-Translation Pipeline
|
||||
|
||||
### generate-multilang.mjs (Google Translate)
|
||||
|
||||
**محرك الترجمة التلقائي الأساسي**— يستخدم برمجة برمجة تطبيقات لترجمة Google إنشاء ترجمات لسلاسل واجهة المستخدم والملفات البرمجة والوثائق.`bash
|
||||
البرامج النصية للعقدة/i18n/generate-multilang.mjs [الرسائل|الملف التمهيدي|المستندات|الكل]`
|
||||
|
||||
| الوضع | ماذا يفعل |
|
||||
| ---------------- | ------------------------------------------------------------------------- |
|
||||
| `الرسائل` | يترجم المفاتيح المفقودة في `src/i18n/messages/{locale}.json` من `en.json` |
|
||||
| "الملف التمهيدي" | يترجم `README.md` إلى كافة اللغات كـ `README.{code}.md` في جذر المشروع |
|
||||
| `المستندات` | يترجم `DOC_SOURCE_FILES` إلى `docs/i18n/{locale}/{docName}` |
|
||||
| `الكل` | يعمل على جميع الأوضاع الثلاثة |
|
||||
|
||||
**الميزات:**
|
||||
|
||||
-**حماية النص**: كتل التعليمات البرمجية للأقنعة (```)، والتعليمات البرمجية المضمنة (`` `)، وروابط/صور تخفيض السعر (`[نص](url)`)، وعلامات HTML، والجداول، والعناصر النائبة لـ ICU (`{count}`، `{value}`، `{total}`، وما إلى ذلك) قبل الترجمة، ثم استعادتها -**التجميع المقسم**: ربط سلاسل متعددة باستخدام محددات `__OMNIROUTE_I18N_SEPARATOR__` لتقليل استدعاءات واجهة برمجة التطبيقات (بحد أقصى 1800 حرف لكل طلب) -**ذاكرة التخزين المؤقت في الذاكرة**: تتجنب استدعاءات واجهة برمجة التطبيقات المتكررة للسلاسل المتكررة خلال الجلسة -**منطق إعادة المحاولة**: التراجع الأسي (حتى 5 محاولات مع 300 مللي ثانية × تأخير المحاولة) للأخطاء 429/5xx -**المهلة**: 20 ثانية لكل طلب -**تخطي الملف الموجود**: إذا كان الملف الهدف موجودًا بالفعل، فلن تتم الكتابة فوقه
|
||||
|
||||
**سلوكيات مهمة:**
|
||||
|
||||
- `docs/i18n/README.md` يتم**إعادة إنشائه**كل مرة — وهو عبارة عن فهرس يتم إنشاؤه تلقائيًا لجميع المستندات
|
||||
- يتم إنشاء ملفات `README.{code}.md` الجذر فقط في حالة عدم وجودها (يتخطى اللغات المحلية في `EXISTING_README_CODES`)
|
||||
- يتم إدراج/تحديث أشرطة اللغة (`🌐**اللغات:**...`) تلقائيًا في جميع المستندات المترجمة### i18n_autotranslate.py (LLM-based)
|
||||
|
||||
**مترجم ثانوي**— يستخدم أي LLM API متوافق مع OpenAI (بما في ذلك OmniRoute نفسه) لترجمة ملفات تخفيض السعر الموجودة `docs/i18n/`. الأفضل لتلميع المستندات أو إعادة ترجمتها بجودة أفضل من ترجمة Google.```bash
|
||||
python3 scripts/i18n_autotranslate.py \
|
||||
--api-url http://localhost:20128/v1 \
|
||||
--api-key sk-your-key \
|
||||
--model gpt-4o
|
||||
|
||||
````
|
||||
|
||||
**الميزات:**
|
||||
|
||||
- يقوم بمسح الملفات المشهورة بسعر رخيص `docs/i18n/` بحثًا عن الفقرات الإنجليزية
|
||||
- تخطي كتل التعليمات البرمجية والبرمجيات والمحتوى المترجم بالفعل
|
||||
- يرسلون الفقرات إلى LLM مع نظام الترجمة الفوري
|
||||
- يدعم جميع اللغات الثلاثين## Validation & QA### validate_translation.py
|
||||
|
||||
**أداة التحقق من صحة الترجمة**— مقارنة أي لغة JSON مع `en.json` وإبلاغ المشكلات.```bash
|
||||
# فحص سريع (التهم فقط)
|
||||
python3 scripts/validate_translation.py fast -l cs
|
||||
# الإخراج:
|
||||
#مفقود: 0
|
||||
# غير مترجم: 0
|
||||
# تم التجاهل (UNTRANSLATABLE_KEYS): 236
|
||||
|
||||
# الفرق التفصيلي حسب الفئة
|
||||
python3 scripts/validate_translation.py diff common -l cs
|
||||
python3 scripts/validate_translation.py إعدادات الفرق -l cs
|
||||
|
||||
# تصدير إلى CSV
|
||||
python3 scripts/validate_translation.py csv -l cs > report.csv
|
||||
|
||||
# تصدير إلى تخفيض السعر
|
||||
python3 scripts/validate_translation.py md -l cs > report.md
|
||||
|
||||
# التقرير الكامل (الافتراضي)
|
||||
python3 scripts/validate_translation.py -l cs```
|
||||
|
||||
**يكتشف:**
|
||||
|
||||
-**المفاتيح المفقودة**— المفاتيح الموجودة في `en.json` ولكن ليست في الملف المحلي
|
||||
-**مفاتيح إضافية**— مفاتيح في ملف الإعدادات المحلية ولكن ليس في `en.json`
|
||||
-**المفاتيح غير المترجمة**— المفاتيح التي تساوي فيها قيمة اللغة المصدر باللغة الإنجليزية (باستثناء القائمة المسموح بها)
|
||||
-**عدم تطابق العناصر النائبة**— العناصر النائبة لـ ICU غير متطابقة بين المصدر والترجمة
|
||||
|
||||
**رموز الخروج:**
|
||||
| الكود | معنى |
|
||||
|------|---------|
|
||||
| 0 | موافق |
|
||||
| 1 | خطأ عام |
|
||||
| 2 | سلاسل مفقودة (خطأ فادح) |
|
||||
| 3 | تحذير غير مترجم (ناعم) |
|
||||
|
||||
**البيئة:**قم بتعيين `TRANSLATION_LANG=cs` أو استخدم علامة `-l cs`.### check_translations.py
|
||||
|
||||
**مدقق المفاتيح Code-to-JSON**— يفحص `src/**/*.tsx` و`src/**/*.ts` لاستدعاءات `useTranslations()` ويتحقق من وجود جميع المفاتيح المشار إليها في `en.json`.```bash
|
||||
# Basic check
|
||||
python3 scripts/check_translations.py
|
||||
|
||||
# Verbose output
|
||||
python3 scripts/check_translations.py --verbose
|
||||
|
||||
# Auto-fix (adds missing keys to en.json)
|
||||
python3 scripts/check_translations.py --fix
|
||||
````
|
||||
|
||||
### generate-qa-checklist.mjs
|
||||
|
||||
**تحليل ثابت وجودة**— يقوم بفحص الملفات صفحة Next.js بحثًا عن مقاييس ألمانية i18n منشئ ويتقرير Markdown.`bash
|
||||
العقدة النصية/i18n/generate-qa-checklist.mjs`
|
||||
|
||||
**الفحوصات:**
|
||||
|
||||
- استخدام فئة العرض الثابت (خطر التجاوز)
|
||||
- فئات الاتجاه لليسار/اليمين (خطر RTL)
|
||||
- الأنماط المعرضة للتقطيع
|
||||
- التكافؤ المحلي (مفاتيح مفقودة/إضافية مقابل `en.json`)
|
||||
- أشرطة تحديد اللغة README في اللغات المحلية ذات الأولوية (`es`، `fr`، `de`، `ja`، `ar`)
|
||||
|
||||
**الإخراج:**`docs/reports/i18n-qa-checklist-{date}.md`### run-visual-qa.mjs
|
||||
|
||||
**Visual QA عبر Playwright**— يلتقط لقطات شاشة لجميع مسارات لوحة المعلومات في مناطق ومنافذ عرض متعددة، ثم يقوم بتقييم صحة الصفحة.```bash
|
||||
|
||||
# Default: es, fr, de, ja, ar on localhost:20128
|
||||
|
||||
node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom base URL and locales
|
||||
|
||||
QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom routes
|
||||
|
||||
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
````
|
||||
|
||||
**اكتشف:**
|
||||
|
||||
- تجاوز النص
|
||||
- قطع العناصر
|
||||
- عدم تطابق تخطيط RTL
|
||||
|
||||
**الإخراج:**`docs/reports/i18n-visual-qa-{date}.md` + تقرير JSON## إدارة المفاتيح غير القابلة للترجمة### untranslatable-keys.json
|
||||
|
||||
**الملف:**`scripts/i18n/untranslatable-keys.json`
|
||||
|
||||
"""""""""""للمفاتيح التي يجب أن تستعين بها للمصدر باللغة الإنجليزية. انتبه بواسطة `validate_translation.py` للإشعارات المسببة لأسباب "غير الترجمة".```json
|
||||
{
|
||||
"description": "المفاتيح التي يجب أن تظل غير مترجمة..."،
|
||||
"مفاتيح": [
|
||||
"النموذج المشترك"،
|
||||
"common.oauth"،
|
||||
"health.cpu"،
|
||||
...
|
||||
]
|
||||
}```
|
||||
|
||||
**ما ينتمي هنا:**
|
||||
|
||||
- أسماء العلامات التجارية/المنتجات: `landing.brandName`، `common.social-github`
|
||||
- المصطلحات/المختصرات الفنية: `health.cpu`، `mcpDashboard.pid`، `settings.ai`
|
||||
- سلاسل ICU/تنسيق: `apiManager.modelsCount`، `health.millithansShort`
|
||||
- قيم العنصر النائب: `providers.openaiBaseUrlPlaceholder`، `cliTools.baseUrlPlaceholder`
|
||||
- أسماء البروتوكولات: `common.http`، `common.oauth`، `providers.oauth2Label`
|
||||
- أقسام التنقل: `sidebar.primarySection`، `sidebar.cliSection`
|
||||
|
||||
**لإضافة مفتاح:**قم بتحرير مصفوفة `المفاتيح` في `scripts/i18n/untranslatable-keys.json` وأعد تشغيل التحقق من الصحة.## CI Integration
|
||||
|
||||
### GitHub Actions (`.github/workflows/ci.yml`)
|
||||
|
||||
يتحقق خط أنابيب CI من صحة جميع اللغات في كل دفعة وPR:
|
||||
|
||||
1.**`i18n-matrix` job**— يكتشف بشكل ديناميكي جميع الملفات المحلية (باستثناء `en.json`)
|
||||
2.**`i18n` job**— يتم تشغيل `validate_translation.py Quick -l '<lang>'` لكل لغة بالتوازي
|
||||
3.**`ci-summary` job**— تجميع النتائج في ملخص لوحة المعلومات```yaml
|
||||
# i18n-matrix: discovers languages
|
||||
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
|
||||
|
||||
# i18n: validates each language
|
||||
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
|
||||
````
|
||||
|
||||
**إخراج لوحة التحكم:**```
|
||||
|
||||
## 🌍 الترجمات
|
||||
|
||||
| متري | القيمة |
|
||||
| ----------------- | ------ |
|
||||
| تم فحص اللغات | 30 |
|
||||
| المجموع غير مترجم | 0 |
|
||||
|
||||
✅جميع الترجمات كاملة```
|
||||
|
||||
## File Structure
|
||||
|
||||
````
|
||||
سرك/i18n/
|
||||
├── config.ts # تعريفات الإعدادات المحلية (30 لغة، تكوين RTL)
|
||||
├── request.ts # دقة لغة وقت التشغيل
|
||||
└── الرسائل/
|
||||
├── ar.json # مصدر الحقيقة (~2800 مفتاح)
|
||||
├── cs.json # الترجمة التشيكية
|
||||
├── de.json # ترجمة ألمانية
|
||||
└── ... إجمالي # 30 ملفًا محليًا
|
||||
|
||||
البرامج النصية/
|
||||
├──i18n/
|
||||
│ ├── generator-multilang.mjs # محرك الترجمة التلقائية (ترجمة جوجل، 888 سطرًا)
|
||||
│ ├── create-qa-checklist.mjs # التحليل الثابت ضمان الجودة
|
||||
│ ├── run-visual-qa.mjs # Playwright visual QA
|
||||
│ └── untranslatable-keys.json # القائمة المسموح بها للتحقق (236 مفتاحًا)
|
||||
├── validate_translation.py # مدقق الترجمة
|
||||
├── check_translations.py # مدقق مفتاح Code-to-JSON
|
||||
└── i18n_autotranslate.py # مترجم مستندات مستند إلى LLM
|
||||
|
||||
.جيثب/سير العمل/
|
||||
└── التحقق من صحة ci.yml # i18n في مصفوفة CI
|
||||
|
||||
المستندات/
|
||||
├── I18N.md # هذا الملف — وثائق سلسلة أدوات i18n
|
||||
├──i18n/
|
||||
│ ├── README.md # فهرس اللغة الذي تم إنشاؤه تلقائيًا
|
||||
│ ├── cs/ # مستندات تشيكية
|
||||
│ │ └── المستندات /
|
||||
│ │ ├── I18N.md # الترجمة التشيكية لهذا الملف
|
||||
│ │ └── ...
|
||||
│ ├── de/ # المستندات الألمانية
|
||||
│ └── ... # 30 دليل محلي
|
||||
└── التقارير/
|
||||
├── i18n-qa-checklist-*.md # تقارير التحليل الثابت
|
||||
└── i18n-visual-qa-*.md # تقارير ضمان الجودة المرئية```
|
||||
|
||||
## Best Practices
|
||||
|
||||
### When Editing Translations
|
||||
|
||||
1.**قم دائمًا بتحرير `en.json` أولاً**— فهو مصدر الحقيقة
|
||||
2.**قم بتشغيل رسائل generator-multilang.mjs**لنشر مفاتيح جديدة لجميع اللغات
|
||||
3.**مراجعة الترجمات التلقائية**— ترجمة Google هي نقطة البداية، وليست نهائية
|
||||
4.**التحقق قبل الالتزام**— `python3 scripts/validate_translation.py Quick -l <lang>`
|
||||
5.**قم بتحديث `untranslatable-keys.json`**إذا كان ينبغي أن يظل المفتاح باللغة الإنجليزية### Placeholder Safety
|
||||
|
||||
- يجب الحفاظ على العناصر النائبة لـ ICU (`{count}`، `{value}`، `{total}`، `{secions}`) تمامًا
|
||||
- يجب أن تحافظ صيغ الجمع (`{count, plural, one {# model} الأخرى {#models}}`) على البنية
|
||||
- يكتشف المدقق عدم تطابق العناصر النائبة تلقائيًا### Adding New Translation Keys in Code
|
||||
|
||||
```tsx
|
||||
// استخدم مفاتيح مساحة الاسم
|
||||
const t = useTranslations("الإعدادات");
|
||||
t("إعدادات ذاكرة التخزين المؤقت"); // يتم تعيينه إلى settings.cacheSettings في JSON
|
||||
|
||||
// قم بتشغيل check_translations.py للتحقق من وجود المفاتيح
|
||||
python3 scripts/check_translations.py --verbose```
|
||||
|
||||
### RTL Considerations
|
||||
|
||||
- العربية (`ar`) والعبرية (`he`) هي لغات RTL
|
||||
- تجنب استخدام لغة CSS ذات الترميز الثابت `left`/`right` - استخدم الخصائص المنطقية `start`/`end`
|
||||
- تكتشف Visual QA عدم تطابق تخطيط RTL عبر "run-visual-qa.mjs".## Known Issues & History
|
||||
|
||||
### `in.json` → `hi.json` Fix
|
||||
|
||||
استخدم المولد في الأصل `الكود: "in"` (كود ترجمة Google المهجور) للغة الهندية بدلاً من ISO 639-1 الصحيح `hi`. أدى هذا إلى إنشاء نسخة معزولة `in.json` من `hi.json`. تم الإصلاح عن طريق تغيير `code: "in"` إلى `code: "hi"` في `generate-multilang.mjs` وإزالة الملف المعزول.### `docs/i18n/README.md` Is Auto-Generated
|
||||
|
||||
تمت إعادة إنشاء الملف "docs/i18n/README.md" بالكامل بواسطة "generate-multilang.mjs docs". سيتم فقدان أي تعديلات يدوية. استخدم `docs/I18N.md` (هذا الملف) للوثائق المكتوبة بخط اليد والتي يجب أن تستمر.### External Untranslatable Keys List
|
||||
|
||||
تم نقل القائمة المسموح بها `untranslatable-keys.json` من مجموعة Python المضمنة في `validate_translation.py` إلى ملف JSON خارجي لتسهيل الصيانة. يقوم المدقق بتحميله في وقت التشغيل.### `generate-multilang.mjs` Hindi Code Fix
|
||||
|
||||
استخدم المولد في الأصل `الكود: "in"` (كود ترجمة Google المهجور) للغة الهندية بدلاً من ISO 639-1 الصحيح `hi`. تم تقديم هذا في الالتزام الأولي `952b0b22c` بواسطة diegosouzapw. تم الإصلاح عن طريق تغيير `code: "in"` إلى `code: "hi"` في مصفوفة `LOCALE_SPECS` وإزالة الملف اليتيم `in.json`.### `validate_translation.py` Ignored Count Output
|
||||
|
||||
يعرض الفحص "السريع" الآن عدد المفاتيح التي تم تجاهلها من "untranslatable-keys.json":```
|
||||
Missing: 0
|
||||
Untranslated: 0
|
||||
Ignored (UNTRANSLATABLE_KEYS): 236
|
||||
````
|
||||
@@ -1,87 +1,72 @@
|
||||
# OmniRoute MCP Server Documentation (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/MCP-SERVER.md) · 🇪🇸 [es](../../es/docs/MCP-SERVER.md) · 🇫🇷 [fr](../../fr/docs/MCP-SERVER.md) · 🇩🇪 [de](../../de/docs/MCP-SERVER.md) · 🇮🇹 [it](../../it/docs/MCP-SERVER.md) · 🇷🇺 [ru](../../ru/docs/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/MCP-SERVER.md) · 🇯🇵 [ja](../../ja/docs/MCP-SERVER.md) · 🇰🇷 [ko](../../ko/docs/MCP-SERVER.md) · 🇸🇦 [ar](../../ar/docs/MCP-SERVER.md) · 🇮🇳 [in](../../in/docs/MCP-SERVER.md) · 🇹🇭 [th](../../th/docs/MCP-SERVER.md) · 🇻🇳 [vi](../../vi/docs/MCP-SERVER.md) · 🇮🇩 [id](../../id/docs/MCP-SERVER.md) · 🇲🇾 [ms](../../ms/docs/MCP-SERVER.md) · 🇳🇱 [nl](../../nl/docs/MCP-SERVER.md) · 🇵🇱 [pl](../../pl/docs/MCP-SERVER.md) · 🇸🇪 [sv](../../sv/docs/MCP-SERVER.md) · 🇳🇴 [no](../../no/docs/MCP-SERVER.md) · 🇩🇰 [da](../../da/docs/MCP-SERVER.md) · 🇫🇮 [fi](../../fi/docs/MCP-SERVER.md) · 🇵🇹 [pt](../../pt/docs/MCP-SERVER.md) · 🇷🇴 [ro](../../ro/docs/MCP-SERVER.md) · 🇭🇺 [hu](../../hu/docs/MCP-SERVER.md) · 🇧🇬 [bg](../../bg/docs/MCP-SERVER.md) · 🇸🇰 [sk](../../sk/docs/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/MCP-SERVER.md) · 🇮🇱 [he](../../he/docs/MCP-SERVER.md) · 🇵🇭 [phi](../../phi/docs/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/MCP-SERVER.md) · 🇨🇿 [cs](../../cs/docs/MCP-SERVER.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/MCP-SERVER.md) · 🇪🇸 [es](../../es/docs/MCP-SERVER.md) · 🇫🇷 [fr](../../fr/docs/MCP-SERVER.md) · 🇩🇪 [de](../../de/docs/MCP-SERVER.md) · 🇮🇹 [it](../../it/docs/MCP-SERVER.md) · 🇷🇺 [ru](../../ru/docs/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/MCP-SERVER.md) · 🇯🇵 [ja](../../ja/docs/MCP-SERVER.md) · 🇰🇷 [ko](../../ko/docs/MCP-SERVER.md) · 🇸🇦 [ar](../../ar/docs/MCP-SERVER.md) · 🇮🇳 [hi](../../hi/docs/MCP-SERVER.md) · 🇮🇳 [in](../../in/docs/MCP-SERVER.md) · 🇹🇭 [th](../../th/docs/MCP-SERVER.md) · 🇻🇳 [vi](../../vi/docs/MCP-SERVER.md) · 🇮🇩 [id](../../id/docs/MCP-SERVER.md) · 🇲🇾 [ms](../../ms/docs/MCP-SERVER.md) · 🇳🇱 [nl](../../nl/docs/MCP-SERVER.md) · 🇵🇱 [pl](../../pl/docs/MCP-SERVER.md) · 🇸🇪 [sv](../../sv/docs/MCP-SERVER.md) · 🇳🇴 [no](../../no/docs/MCP-SERVER.md) · 🇩🇰 [da](../../da/docs/MCP-SERVER.md) · 🇫🇮 [fi](../../fi/docs/MCP-SERVER.md) · 🇵🇹 [pt](../../pt/docs/MCP-SERVER.md) · 🇷🇴 [ro](../../ro/docs/MCP-SERVER.md) · 🇭🇺 [hu](../../hu/docs/MCP-SERVER.md) · 🇧🇬 [bg](../../bg/docs/MCP-SERVER.md) · 🇸🇰 [sk](../../sk/docs/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/MCP-SERVER.md) · 🇮🇱 [he](../../he/docs/MCP-SERVER.md) · 🇵🇭 [phi](../../phi/docs/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/MCP-SERVER.md) · 🇨🇿 [cs](../../cs/docs/MCP-SERVER.md) · 🇹🇷 [tr](../../tr/docs/MCP-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
> Model Context Protocol server with 16 intelligent tools
|
||||
> المدرسة التمهيدية النموذجية المزود بـ 16 أداة ذكية## تثبيت
|
||||
|
||||
## تثبيت
|
||||
OmniRoute MCP المدمج. ابدأ بـ:`bash
|
||||
الطريق الشامل --mcp`
|
||||
|
||||
OmniRoute MCP is built-in. Start it with:
|
||||
أو عبر النقل المفتوح:```bash
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Or via the open-sse transport:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
|
||||
```
|
||||
|
||||
## IDE Configuration
|
||||
|
||||
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
|
||||
مراجعة تكوينات IDE](integrations/ide-configs.md) التوجه إلى إعداد Antigravity وCursor وCopilot وClaude Desktop.---## Essential Tools (8)
|
||||
|
||||
---
|
||||
|
||||
## Essential Tools (8)
|
||||
|
||||
| Tool | Description |
|
||||
| أداة | الوصف |
|
||||
| :------------------------------ | :--------------------------------------- |
|
||||
| `omniroute_get_health` | Gateway health, circuit breakers, uptime |
|
||||
| `omniroute_list_combos` | All configured combos with models |
|
||||
| `omniroute_get_combo_metrics` | Performance metrics for a specific combo |
|
||||
| `omniroute_switch_combo` | Switch active combo by ID/name |
|
||||
| `omniroute_check_quota` | Quota status per provider or all |
|
||||
| `omniroute_route_request` | Send a chat completion through OmniRoute |
|
||||
| `omniroute_cost_report` | Cost analytics for a time period |
|
||||
| `omniroute_list_models_catalog` | Full model catalog with capabilities |
|
||||
| `omniroute_get_health` | صحة البوابة، قواطع الضوء، الجهوزية |
|
||||
| `omniroute_list_combos` | جميع المجموعات التي تم اختيارها مع الارتباطات |
|
||||
| `omniroute_get_combo_metrics` | مقاييس محددة |
|
||||
| `omniroute_switch_combo` | تعديل التحرير والسرد فقط حسب المعرف/الاسم |
|
||||
| `omniroute_check_quota` | حالة الحصة لكل ما يتعلق أو الكل |
|
||||
| `omniroute_route_request` | استكمال الدردشة من خلال OmniRoute |
|
||||
| `تقرير رحلة_الطريق الشامل` | تحليلات التكلفة لوقت طويل |
|
||||
| `omniroute_list_models_catalog` | كتالوج نموذجي كامل مع رموزيات |## أدوات متقدمة (8)
|
||||
|
||||
## Advanced Tools (8)
|
||||
|
||||
| Tool | Description |
|
||||
| أداة | الوصف |
|
||||
| :--------------------------------- | :---------------------------------------------------------- |
|
||||
| `omniroute_simulate_route` | Dry-run routing simulation with fallback tree |
|
||||
| `omniroute_set_budget_guard` | Session budget with degrade/block/alert actions |
|
||||
| `omniroute_set_resilience_profile` | Apply conservative/balanced/aggressive preset |
|
||||
| `omniroute_test_combo` | Live-test all models in a combo via a real upstream request |
|
||||
| `omniroute_get_provider_metrics` | Detailed metrics for one provider |
|
||||
| `omniroute_best_combo_for_task` | Task-fitness recommendation with alternatives |
|
||||
| `omniroute_explain_route` | Explain a past routing decision |
|
||||
| `omniroute_get_session_snapshot` | Full session state: costs, tokens, errors |
|
||||
| `omniroute_simulate_route` | المحاكاة الجافة باستخدام الشجرة التقليدية |
|
||||
| `omniroute_set_budget_guard` | ضبط إجراءات مع التخفيض/الحظر/التنبيه |
|
||||
| `omniroute_set_resilience_profile` | التقدم نحو التقدم/المتوازن/العدواني |
|
||||
| `omniroute_test_combo` | تم اختباره بشكل مباشر لجميع الاتجاهات في مجموعة من خلال طلب حقيقي للمنبع |
|
||||
| `omniroute_get_provider_metrics` | معايير محددة لمزود واحد |
|
||||
| `omniroute_best_combo_for_task` | وصفة بملاءة المهام مع البدائل |
|
||||
| `omniroute_explain_route` | شرح الوضع السابق |
|
||||
| `omniroute_get_session_snapshot` | ملحوظة: التكاليف والرموز والأخطاء |## Authentication
|
||||
|
||||
## Authentication
|
||||
تم مصادقة أدوات MCP عبر نطاقات المفاتيح API. متطلبات كل أدوات النطاقات المحددة:
|
||||
|
||||
MCP tools are authenticated via API key scopes. Each tool requires specific scopes:
|
||||
|
||||
| Scope | Tools |
|
||||
| النطاق | أدوات |
|
||||
| :------------- | :----------------------------------------------- |
|
||||
| `read:health` | get_health, get_provider_metrics |
|
||||
| `read:combos` | list_combos, get_combo_metrics |
|
||||
| `write:combos` | switch_combo |
|
||||
| `read:quota` | check_quota |
|
||||
| `write:route` | route_request, simulate_route, test_combo |
|
||||
| `read:usage` | cost_report, get_session_snapshot, explain_route |
|
||||
| `write:config` | set_budget_guard, set_resilience_profile |
|
||||
| `read:models` | list_models_catalog, best_combo_for_task |
|
||||
| `اقرأ:الصحة` | get_health، get_provider_metrics |
|
||||
| `اقرأ: المجموعات` | list_combos، get_combo_metrics |
|
||||
| `اكتب: المجموعات` | Switch_combo |
|
||||
| `اقرأ: الحصة` | check_quota |
|
||||
| `اكتب: الطريق` | طلب_الطريق، محاكاة_الطريق، اختبار_كومبو |
|
||||
| `قراءة:استخدام` | إقرار التكلفة، الحصول على لقطة_الجلسة، شرح_الطريق |
|
||||
| `الكتابة: إستبدل` | set_budget_guard، set_resilience_profile |
|
||||
| `اقرأ:النماذج` | list_models_catalog، best_combo_for_task |## تسجيل التدقيق
|
||||
|
||||
## Audit Logging
|
||||
يتم تسجيل كل الاتصال للأداة في `mcp_tool_audit` باستخدام:
|
||||
|
||||
Every tool call is logged to `mcp_tool_audit` with:
|
||||
- اسم الأداة، والوسائط، والنتيجة
|
||||
- المدة (مللي ثانية)، النجاح/الفشل
|
||||
- تجزئة مفتاح API، الأثر العمري## Files
|
||||
|
||||
- Tool name, arguments, result
|
||||
- Duration (ms), success/failure
|
||||
- API key hash, timestamp
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| ملف | الحصاد |
|
||||
| :------------------------------------------- | :------------------------------------------ |
|
||||
| `open-sse/mcp-server/server.ts` | MCP server creation + 16 tool registrations |
|
||||
| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport |
|
||||
| `open-sse/mcp-server/auth.ts` | API key + scope validation |
|
||||
| `open-sse/mcp-server/audit.ts` | Tool call audit logging |
|
||||
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced tool handlers |
|
||||
| `open-sse/mcp-server/server.ts` | إنشاء خادم MCP + تسجيل 16 أداة |
|
||||
| `open-sse/mcp-server/transport.ts` | نقل Stdio + HTTP |
|
||||
| `open-sse/mcp-server/auth.ts` | مفتاح API + التحقق من صحة النطاق |
|
||||
| `open-sse/mcp-server/audit.ts` | تسجيل تدقيق الاتصال بالأداة |
|
||||
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 معالجات وأدوات متقدمة |
|
||||
```
|
||||
|
||||
@@ -1,37 +1,26 @@
|
||||
# Release Checklist (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../es/docs/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../fr/docs/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../de/docs/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../it/docs/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../ru/docs/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../ja/docs/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../ko/docs/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../ar/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../../in/docs/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../th/docs/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../vi/docs/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../id/docs/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../ms/docs/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../nl/docs/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../pl/docs/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../sv/docs/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../no/docs/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../da/docs/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../fi/docs/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../pt/docs/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../ro/docs/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../hu/docs/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../bg/docs/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../sk/docs/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../he/docs/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../phi/docs/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../cs/docs/RELEASE_CHECKLIST.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../es/docs/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../fr/docs/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../de/docs/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../it/docs/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../ru/docs/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../ja/docs/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../ko/docs/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../ar/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [hi](../../hi/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../../in/docs/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../th/docs/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../vi/docs/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../id/docs/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../ms/docs/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../nl/docs/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../pl/docs/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../sv/docs/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../no/docs/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../da/docs/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../fi/docs/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../pt/docs/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../ro/docs/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../hu/docs/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../bg/docs/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../sk/docs/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../he/docs/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../phi/docs/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../cs/docs/RELEASE_CHECKLIST.md) · 🇹🇷 [tr](../../tr/docs/RELEASE_CHECKLIST.md)
|
||||
|
||||
---
|
||||
|
||||
Use this checklist before tagging or publishing a new OmniRoute release.
|
||||
استخدم قائمة التحقق هذه قبل وضع علامة على إصدار OmniRoute الجديد أو نشره.## الإصدار وسجل التغيير
|
||||
|
||||
## Version and Changelog
|
||||
|
||||
1. Bump `package.json` version (`x.y.z`) in the release branch.
|
||||
2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
|
||||
1. قم بتثبيت الإصدار `package.json` (`x.y.z`) في فرع الإصدار.
|
||||
2. انقل نسخة التعليقات من `## [Unreleased]` في `CHANGELOG.md` إلى قسم المؤرخ:
|
||||
- `## [x.y.z] — YYYY-MM-DD`
|
||||
3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
|
||||
4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
|
||||
3. يستخدم بـ `## [Unreleased]` كقسم جديد للعمل القادم القادم.
|
||||
4. تأكد من أن أحدث قسم في `CHANGELOG.md` يساوي الإصدار `package.json`.## API Docs
|
||||
|
||||
## API Docs
|
||||
5. قم بزيارة "docs/openapi.yaml":
|
||||
- يجب أن يكون `info.version` مساويًا لإصدار `package.json`.
|
||||
6. التحقق من صحة الأمثلة على نقاط نهائية في حالة عدة عقود API.## Runtime Docs
|
||||
|
||||
1. Update `docs/openapi.yaml`:
|
||||
- `info.version` must equal `package.json` version.
|
||||
2. Validate endpoint examples if API contracts changed.
|
||||
7. قم بمراجعة docs/ARCHITECTURE.md للتخزين/وقت التشغيل.
|
||||
8. راجع `docs/TROUBLESHOOTING.md` بحثًا عن env var والانجراف التشغيلي.
|
||||
9. قم بزيارة الموقع بشكل غير المترجم إذا تغيرت مصدر العشب ملحوظة.## الفحص الآلي
|
||||
|
||||
## Runtime Docs
|
||||
يُسمح له بالسيطرة المحلية قبل فتح العلاقات العامة:`bash
|
||||
التحقق من تشغيل npm:docs-sync`
|
||||
|
||||
1. Review `docs/ARCHITECTURE.md` for storage/runtime drift.
|
||||
2. Review `docs/TROUBLESHOOTING.md` for env var and operational drift.
|
||||
3. Update localized docs if source docs changed significantly.
|
||||
|
||||
## Automated Check
|
||||
|
||||
Run the sync guard locally before opening PR:
|
||||
|
||||
```bash
|
||||
npm run check:docs-sync
|
||||
```
|
||||
|
||||
CI also runs this check in `.github/workflows/ci.yml` (lint job).
|
||||
يقوم CI أيضًا بتشغيل هذا الفحص في `.github/workflows/ci.yml` (مهمة الوبر).
|
||||
|
||||
@@ -1,95 +1,68 @@
|
||||
# Troubleshooting (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/TROUBLESHOOTING.md) · 🇪🇸 [es](../../es/docs/TROUBLESHOOTING.md) · 🇫🇷 [fr](../../fr/docs/TROUBLESHOOTING.md) · 🇩🇪 [de](../../de/docs/TROUBLESHOOTING.md) · 🇮🇹 [it](../../it/docs/TROUBLESHOOTING.md) · 🇷🇺 [ru](../../ru/docs/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/TROUBLESHOOTING.md) · 🇯🇵 [ja](../../ja/docs/TROUBLESHOOTING.md) · 🇰🇷 [ko](../../ko/docs/TROUBLESHOOTING.md) · 🇸🇦 [ar](../../ar/docs/TROUBLESHOOTING.md) · 🇮🇳 [in](../../in/docs/TROUBLESHOOTING.md) · 🇹🇭 [th](../../th/docs/TROUBLESHOOTING.md) · 🇻🇳 [vi](../../vi/docs/TROUBLESHOOTING.md) · 🇮🇩 [id](../../id/docs/TROUBLESHOOTING.md) · 🇲🇾 [ms](../../ms/docs/TROUBLESHOOTING.md) · 🇳🇱 [nl](../../nl/docs/TROUBLESHOOTING.md) · 🇵🇱 [pl](../../pl/docs/TROUBLESHOOTING.md) · 🇸🇪 [sv](../../sv/docs/TROUBLESHOOTING.md) · 🇳🇴 [no](../../no/docs/TROUBLESHOOTING.md) · 🇩🇰 [da](../../da/docs/TROUBLESHOOTING.md) · 🇫🇮 [fi](../../fi/docs/TROUBLESHOOTING.md) · 🇵🇹 [pt](../../pt/docs/TROUBLESHOOTING.md) · 🇷🇴 [ro](../../ro/docs/TROUBLESHOOTING.md) · 🇭🇺 [hu](../../hu/docs/TROUBLESHOOTING.md) · 🇧🇬 [bg](../../bg/docs/TROUBLESHOOTING.md) · 🇸🇰 [sk](../../sk/docs/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/TROUBLESHOOTING.md) · 🇮🇱 [he](../../he/docs/TROUBLESHOOTING.md) · 🇵🇭 [phi](../../phi/docs/TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/TROUBLESHOOTING.md) · 🇨🇿 [cs](../../cs/docs/TROUBLESHOOTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/TROUBLESHOOTING.md) · 🇪🇸 [es](../../es/docs/TROUBLESHOOTING.md) · 🇫🇷 [fr](../../fr/docs/TROUBLESHOOTING.md) · 🇩🇪 [de](../../de/docs/TROUBLESHOOTING.md) · 🇮🇹 [it](../../it/docs/TROUBLESHOOTING.md) · 🇷🇺 [ru](../../ru/docs/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/TROUBLESHOOTING.md) · 🇯🇵 [ja](../../ja/docs/TROUBLESHOOTING.md) · 🇰🇷 [ko](../../ko/docs/TROUBLESHOOTING.md) · 🇸🇦 [ar](../../ar/docs/TROUBLESHOOTING.md) · 🇮🇳 [hi](../../hi/docs/TROUBLESHOOTING.md) · 🇮🇳 [in](../../in/docs/TROUBLESHOOTING.md) · 🇹🇭 [th](../../th/docs/TROUBLESHOOTING.md) · 🇻🇳 [vi](../../vi/docs/TROUBLESHOOTING.md) · 🇮🇩 [id](../../id/docs/TROUBLESHOOTING.md) · 🇲🇾 [ms](../../ms/docs/TROUBLESHOOTING.md) · 🇳🇱 [nl](../../nl/docs/TROUBLESHOOTING.md) · 🇵🇱 [pl](../../pl/docs/TROUBLESHOOTING.md) · 🇸🇪 [sv](../../sv/docs/TROUBLESHOOTING.md) · 🇳🇴 [no](../../no/docs/TROUBLESHOOTING.md) · 🇩🇰 [da](../../da/docs/TROUBLESHOOTING.md) · 🇫🇮 [fi](../../fi/docs/TROUBLESHOOTING.md) · 🇵🇹 [pt](../../pt/docs/TROUBLESHOOTING.md) · 🇷🇴 [ro](../../ro/docs/TROUBLESHOOTING.md) · 🇭🇺 [hu](../../hu/docs/TROUBLESHOOTING.md) · 🇧🇬 [bg](../../bg/docs/TROUBLESHOOTING.md) · 🇸🇰 [sk](../../sk/docs/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/TROUBLESHOOTING.md) · 🇮🇱 [he](../../he/docs/TROUBLESHOOTING.md) · 🇵🇭 [phi](../../phi/docs/TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/TROUBLESHOOTING.md) · 🇨🇿 [cs](../../cs/docs/TROUBLESHOOTING.md) · 🇹🇷 [tr](../../tr/docs/TROUBLESHOOTING.md)
|
||||
|
||||
---
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
المشاكل والحلول الشائعة لـ OmniRoute.---## Quick Fixes
|
||||
|
||||
---
|
||||
|
||||
## Quick Fixes
|
||||
|
||||
| Problem | Solution |
|
||||
| ----------------------------- | ------------------------------------------------------------------ |
|
||||
| First login not working | Set `INITIAL_PASSWORD` in `.env` (no hardcoded default) |
|
||||
| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| No 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) |
|
||||
|
||||
---
|
||||
|
||||
## Provider Issues
|
||||
| مشكلة | الحل |
|
||||
| ------------------------------------- | --------------------------------------------------------------------- | --------------------- |
|
||||
| تسجيل الدخول الأول لا يعمل | قم بزيارة `INITIAL_PASSWORD` في `.env` (بدون ترميز افتراضي) |
|
||||
| بدأت لوحة المعلومات على المنفذ الخاطئ | قم بزيارة `PORT=20128` و`NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| لا توجد سجلات للطلب ضمن `السجلات/` | اضبط `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: تم رفض الإذن | اضبط `DATA_DIR=/path/to/writable/dir` لتجاوز `~/.omniroute` |
|
||||
| استراتيجية لا تنقذ | التحديث إلى الإصدار 1.4.11+ (إصلاح مخطط Zod لاستمرارية الإعدادات) | ---## Provider Issues |
|
||||
|
||||
### "Language model did not provide messages"
|
||||
|
||||
**Cause:** Provider quota exhausted.
|
||||
**السبب:**استنفدت حصة الموفر.
|
||||
|
||||
**Fix:**
|
||||
**الإصلاح:**
|
||||
|
||||
1. Check dashboard quota tracker
|
||||
2. Use a combo with fallback tiers
|
||||
3. Switch to cheaper/free tier
|
||||
1. تحقق من تعقب الحصص في لوحة القيادة
|
||||
2. استخدم المجموعة من المستويات التجريبية
|
||||
3. قم بالبديل إلى اللغة اللاتينية الأرخص/المجانية### تحديد المعدل
|
||||
|
||||
### Rate Limiting
|
||||
**السبب:**استنفدت حصة الاشتراك.
|
||||
|
||||
**Cause:** Subscription quota exhausted.
|
||||
**الإصلاح:**
|
||||
|
||||
**Fix:**
|
||||
- إضافة بيع: `cc/clude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- استخدم GLM/MiniMax كنسخة بيعية بسعر رخيص### OAuth Token منتهي الصلاحية
|
||||
|
||||
- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Use GLM/MiniMax as cheap backup
|
||||
يقوم OmniRoute بكتابة الشعارات المميزة. إذا كانت هناك مشاكل:
|
||||
|
||||
### OAuth Token Expired
|
||||
|
||||
OmniRoute auto-refreshes tokens. If issues persist:
|
||||
|
||||
1. Dashboard → Provider → Reconnect
|
||||
2. Delete and re-add the provider connection
|
||||
|
||||
---
|
||||
|
||||
## Cloud Issues
|
||||
1. لوحة المعلومات → الموفر → إعادة الاتصال
|
||||
2. قم بإلغاء الحذف وإضافة اتصال الموفر---## Cloud Issues
|
||||
|
||||
### Cloud Sync Errors
|
||||
|
||||
1. Verify `BASE_URL` points to your running instance (e.g., `http://localhost:20128`)
|
||||
2. Verify `CLOUD_URL` points to your cloud endpoint (e.g., `https://omniroute.dev`)
|
||||
3. Keep `NEXT_PUBLIC_*` values aligned with server-side values
|
||||
1. تحقق من نقاط `BASE_URL` لمثيلك قيد التشغيل (على سبيل المثال، `http://localhost:20128`)
|
||||
2. تحقق من نقاط `CLOUD_URL` إلى نقطة نهاية السحابة الخاصة بك (على سبيل المثال، `https://omniroute.dev`)
|
||||
3. حافظ على قيم `NEXT_PUBLIC_*` مع قيم من جانب العمال### Cloud `stream=false` Returns 500
|
||||
|
||||
### Cloud `stream=false` Returns 500
|
||||
**العلامة:**`الرمز المميز 'd'...' غير متوقع في نقطة نهاية السحابة للمكالمات غير المتدفقة.
|
||||
|
||||
**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
|
||||
**السبب:**يقوم المنبع بإرجاع حمولة SSE أثناء العميل JSON.
|
||||
|
||||
**Cause:** Upstream returns SSE payload while client expects JSON.
|
||||
**الحل البديل:**استخدم `stream=true` للمكالمات السحابية المباشرة. قم بتضمين SSE المحلي → JSON الاحتياطي.### السحابة تقول أنها متصلة ولكن "مفتاح API غير صالح"
|
||||
|
||||
**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback.
|
||||
|
||||
### Cloud Says Connected but "Invalid API key"
|
||||
|
||||
1. Create a fresh key from local dashboard (`/api/keys`)
|
||||
2. Run cloud sync: Enable Cloud → Sync Now
|
||||
3. Old/non-synced keys can still return `401` on cloud
|
||||
|
||||
---
|
||||
|
||||
## Docker Issues
|
||||
1. أنشئ مفتاحًا جديدًا من لوحة التحكم المحلية (`/api/keys`)
|
||||
2. قم بتشغيل البروتوكولات السحابية: قم بتمكين السحابة → النوبات الآن
|
||||
3. لا يزال بإمكانها المفاتيح القديمة/غير المتزامنة إرجاع "401" على السحابة---## Docker Issues
|
||||
|
||||
### CLI Tool Shows Not Installed
|
||||
|
||||
1. Check runtime fields: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. For portable mode: use image target `runner-cli` (bundled CLIs)
|
||||
3. For host mount mode: set `CLI_EXTRA_PATHS` and mount host bin directory as read-only
|
||||
4. If `installed=true` and `runnable=false`: binary was found but failed healthcheck
|
||||
1. تحقق من استهلاك وقت التشغيل: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. بالنسبة لوضع الهاتف المحمول: استخدم الصورة الهدف `runner-cli` (CLIs المجمعة)
|
||||
3. بالنسبة لصلاحية التثبيت المحلية: قم بـ `CLI_EXTRA_PATHS` وتثبيت دليل المضيفة للقراءة فقط
|
||||
4. إذا كان "تم التثبيت = صحيح" و"قابل للتشغيل = خطأ": تم العثور على الملف الثنائي ولكن فشل التحقق من الصحة### Quick Runtime Validation```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
|
||||
### Quick Runtime Validation
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -97,160 +70,106 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
|
||||
|
||||
### High Costs
|
||||
|
||||
1. Check usage stats in Dashboard → Usage
|
||||
2. Switch primary model to GLM/MiniMax
|
||||
3. Use free tier (Gemini CLI, Qoder) for non-critical tasks
|
||||
4. Set cost budgets per API key: Dashboard → API Keys → Budget
|
||||
|
||||
---
|
||||
|
||||
## Debugging
|
||||
1. التحقق من إحصائيات استخدام لوحة المعلومات →
|
||||
2. قم باستبدال النموذج الأساسي بـ GLM/MiniMax
|
||||
3. استخدم طلب التقديم (Gemini CLI، Qoder) للمهام غير المرغوب فيه
|
||||
4. قم بإنشاء اقتصاديات التكلفة لكل مفتاح برمجة التطبيقات: لوحة المعلومات ← مفاتيح برمجة التطبيقات ← الميزانية---## Debugging
|
||||
|
||||
### Enable Request Logs
|
||||
|
||||
Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory.
|
||||
|
||||
### Check Provider Health
|
||||
|
||||
```bash
|
||||
قم بزيارة `ENABLE_REQUEST_LOGS=true` في ملف `.env` الخاص بك. تسجيل سجلات ضمن دليل "السجلات/".### التحقق من صحة المزود```bash
|
||||
# Health dashboard
|
||||
http://localhost:20128/dashboard/health
|
||||
|
||||
# API health check
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
````
|
||||
|
||||
### Runtime Storage
|
||||
|
||||
- Main state: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings)
|
||||
- Usage: SQLite tables in `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + optional `${DATA_DIR}/log.txt` and `${DATA_DIR}/call_logs/`
|
||||
- Request logs: `<repo>/logs/...` (when `ENABLE_REQUEST_LOGS=true`)
|
||||
|
||||
---
|
||||
|
||||
## Circuit Breaker Issues
|
||||
- الحالة الرئيسية: `${DATA_DIR}/storage.sqlite` (الموفرون، المجموعات، الأسماء المستعارة، المفاتيح، الإعدادات)
|
||||
-استخدام: جداول SQLite في `storage.sqlite` (`usage_history`، `call_logs`، `proxy_logs`) + اختياري `${DATA_DIR}/log.txt` و`${DATA_DIR}/call_logs/`
|
||||
- أرشيف الطلب: `<repo>/logs/...` (عندما يكون `ENABLE_REQUEST_LOGS=true`)---## Circuit Breaker Issues
|
||||
|
||||
### Provider stuck in OPEN state
|
||||
|
||||
When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
|
||||
عندما يكون حظر دائرة الموفر مفتوحًا، يتم حظره حتى نهاية فترة التهدئة.
|
||||
|
||||
**Fix:**
|
||||
**الإصلاح:**
|
||||
|
||||
1. Go to **Dashboard → Settings → Resilience**
|
||||
2. Check the circuit breaker card for the affected provider
|
||||
3. Click **Reset All** to clear all breakers, or wait for the cooldown to expire
|
||||
4. Verify the provider is actually available before resetting
|
||||
1. انتقل إلى**لوحة التحكم ← الإعدادات ← طيران**
|
||||
2. التحقق من بطاقة القاطع الكهربائي الخاصة بالمزود المتأثر
|
||||
3. انقر فوق**إعادة تعيين الكل**لمسح جميع القواطع، أو انتظر حتى انتهاء فترة التهدئة
|
||||
4. التحقق من أن الموفر فعلياً قبل العودة### مقدم الخدمة يستمر في قطع قاطع الدائرة الكهربائية
|
||||
|
||||
### Provider keeps tripping the circuit breaker
|
||||
إذا وصلت الخدمة بشكل عام في الحالة المفتوحة:
|
||||
|
||||
If a provider repeatedly enters OPEN state:
|
||||
|
||||
1. Check **Dashboard → Health → Provider Health** for the failure pattern
|
||||
2. Go to **Settings → Resilience → Provider Profiles** and increase the failure threshold
|
||||
3. Check if the provider has changed API limits or requires re-authentication
|
||||
4. Review latency telemetry — high latency may cause timeout-based failures
|
||||
|
||||
---
|
||||
|
||||
## Audio Transcription Issues
|
||||
1. تحقق من**لوحة التحكم ← الصحة ← صحة مقدم الخدمة**نمط المعرفة تبني
|
||||
2. انتقل إلى**الإعدادات → اختلاف → ملفات تعريف الموفر**وكم حتى حد ما
|
||||
3. تحقق مما إذا كان الموفر قد قام بتغيير حدود واجهة برمجة التطبيقات (API) أو طلب إعادة المصادقة
|
||||
4. قم بمراجعة القياس عن بعد لزمن التعرض - قد يتسبب في حدوث التأثيرات الناتجة في سبب واحد بسبب انتهاء المهلة---## Audio Transcription Issues
|
||||
|
||||
### "Unsupported model" error
|
||||
|
||||
- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
|
||||
- Verify the provider is connected in **Dashboard → Providers**
|
||||
- تأكد من أنك تستخدم القواعد الصحيحة: `deepgram/nova-3` أو `assemblyai/best`
|
||||
- تحقق من أن الموفر متصل في**لوحة التحكم ← الموفرون**### يعود النسخ فارغًا أو فاشلًا
|
||||
|
||||
### Transcription returns empty or fails
|
||||
- التحقق من تنسيقات الصوت المدعومة: `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`
|
||||
- التحقق من أن حجم الملف يقع ضمن حدود الموفر (عادةً أقل من 25 ميجابايت)
|
||||
- التحقق من صلاحية مفتاح API الخاص بالموفر في البطاقة المزودة---## Translator Debugging
|
||||
|
||||
- Check supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Verify file size is within provider limits (typically < 25MB)
|
||||
- Check provider API key validity in the provider card
|
||||
استخدم**لوحة المعلومات → المترجم**لتصحيح المناسب لرغبتك:
|
||||
|
||||
---
|
||||
| الوضع | متى تستخدم |
|
||||
| ------------------ | ------------------------------------------------------------------------------ | -------------------------- |
|
||||
| **ساحة اللعب** | قارن ملفات الإدخال/الإخراج جنباً إلى جنب — لا لصق طلباً فاشلاً لترى كيف ترجمته |
|
||||
| **اختبار الدردشة** | أرسل الرسائل مباشرة وافحص فاعلية الطلب/الاستجابة الكاملة بما في ذلك الرؤوس |
|
||||
| **الاختبار** | قم بإنهاء الفقرات المجمعة عبر مجموعات محددة على الترجمات المعطلة |
|
||||
| **مراقبة حية** | شاهد تدفق الطلبات في التنسيق المطلوب على الترجمة المتقطعة | ### مشكلات التنسيق الشائعة |
|
||||
|
||||
## Translator Debugging
|
||||
|
||||
Use **Dashboard → Translator** to debug format translation issues:
|
||||
|
||||
| Mode | When to Use |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------- |
|
||||
| **Playground** | Compare input/output formats side by side — paste a failing request to see how it translates |
|
||||
| **Chat Tester** | Send live messages and inspect the full request/response payload including headers |
|
||||
| **Test Bench** | Run batch tests across format combinations to find which translations are broken |
|
||||
| **Live Monitor** | Watch real-time request flow to catch intermittent translation issues |
|
||||
|
||||
### Common format issues
|
||||
|
||||
- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting
|
||||
- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode
|
||||
- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output
|
||||
- **SDK returns raw string instead of object** — 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`
|
||||
|
||||
---
|
||||
|
||||
## Resilience Settings
|
||||
-**لا تضع علامات التفكير**— تحقق مما إذا كان الموفر المستهدف مقبولاً يمكن توقعه -**استدعاءات مساعدة**— قد توفر بعض الترجمات بشكل فعال لحذف الأشخاص غير المساعدين؛ تحقق في وضع الملعب -**مطالبة النظام مفقودة**— نظام Claude وGemini مع المطالبات المختلفة؛ التحقق من إخراج الترجمة -**ترجع سلسلة SDK أولية أخرى من**- تم إصلاح ذلك في الإصدار 1.1.0: تقوم أداة التأثير الفوري الآن وأنواعها غير الممتازة (`x_groq`، و`usage_breakdown`، وما إلى ذلك) التي فشلت في التحقق من صحة OpenAI SDK Pydantic -**GLM/ERNIE يرفض دور `النظام`**- تم إصلاحه في الإصدار 1.1.0: يقوم بـ«تطبيع الدور التنفيذي برسائل مدمجة في النظام في رسائل المستخدم للنماذج غير المتوافقة» -**لم يتم التعرف على دور "المطور"**- تم إصلاحه في الإصدار 1.1.0: تم تحويله تلقائياً إلى "نظام" لتقديم الخدمات غير التابعة لـ OpenAI -**`json_schema` لا يعمل مع Gemini**— تم إصلاحه في الإصدار 1.1.0: تم الآن تحويل `response_format` إلى `responseMimeType` + `responseSchema` الخاص بـ Gemini---## Resilience Settings
|
||||
|
||||
### Auto rate-limit not triggering
|
||||
|
||||
- Auto rate-limit only applies to API key providers (not OAuth/subscription)
|
||||
- Verify **Settings → Resilience → Provider Profiles** has auto-rate-limit enabled
|
||||
- Check if the provider returns `429` status codes or `Retry-After` headers
|
||||
- يُطبق حتى يتم التعديل تلقائيًا فقط على لوحة مفاتيح برمجة التطبيقات (وليس OAuth/الاشتراك)
|
||||
- تحقق من أن**الإعدادات → ← ملفات تعريف الموفر**تم وأيضا تعديلها بشكل تلقائي
|
||||
- تحقق مما إذا كان الموفر يعرض رموز الحالة "429" أو الذاكرة "إعادة المحاولة بعد".### ضبط التراجع الأسي
|
||||
|
||||
### Tuning exponential backoff
|
||||
تدعم ملفات تعريف الموفر هذه الإعدادات:
|
||||
|
||||
Provider profiles support these settings:
|
||||
-**التأخير الأساسي**— وقت الانتظار الأول بعد الأول (الافتراضي: 1 ثانية) -**الحد الأقصى للتأخير**— الحد الأقصى لوقت الانتظار (الافتراضي: 30 ثانية) -**المضاعف**— كمية الزيادة الشاملة لكل فشل متتالي (الافتراضي: 2x)### قطيع مضاد الرعد
|
||||
|
||||
- **Base delay** — Initial wait time after first failure (default: 1s)
|
||||
- **Max delay** — Maximum wait time cap (default: 30s)
|
||||
- **Multiplier** — How much to increase delay per consecutive failure (default: 2x)
|
||||
عندما تصل العديد من الطلبات المتزامنة إلى وفرة السعر، يستخدم تقنية OmniRoute تقنية Mutex + تحديد موعد مباشر لتنزيل الطلبات مباشرة من أجل توقف الحالات المتتالية. وهذا تلقائي لموفري مفاتيح API.---## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
|
||||
### Anti-thundering herd
|
||||
يقوم بعض مستخدمي OmniRoute بالتحرك أمام RAG أو مكدسات الوكيل. في هذه الإعدادات، من الشائع رؤية نمط غريب: يبدو OmniRoute سليمًا (مقدمو خدمة في وضع جيد، وإصدار الأحكام الشخصية على ما بعد، ولا توجد تنبيهات بخلاف حدود القضاء) ولكن الإجابة لا تزال لا تزال صحيحة.
|
||||
|
||||
When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex + auto rate-limiting to serialize requests and prevent cascading failures. This is automatic for API key providers.
|
||||
ومن ثم، يأتي هذا الذي يأتي من خط الأنابيب النهائي RAG، وليس من نفسه.
|
||||
|
||||
---
|
||||
إذا كنت تريد مفردات الحصول على وصف لتلك الإخفاقات، فيمكنك استخدام WFGY IssueMap، وهو مصدر ترخيص MIT الخارجي يحدد ستة عشرة نمطًاًا لفشل RAG / LLM. على مستوى عال يغطي:
|
||||
|
||||
## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
- الانجراف استرجاع وحدود السياقة المكسورة
|
||||
- الفهارس الفارغة أو القديمة ومخازن المتجهات
|
||||
- التضمين مقابل عدم التطابق الدلالي
|
||||
- رخص السياقة ورافعة السياقة
|
||||
- مجموعة واسعة من الإجابات الاستخدام في التجارة الحرة
|
||||
- خلل في النص بين النص والوكيل
|
||||
- ذاكرة متعددة للعامل والمؤثرات
|
||||
- مشاكل النشر والتمهيد
|
||||
|
||||
Some OmniRoute users place the gateway in front of RAG or agent stacks. In those setups it is common to see a strange pattern: OmniRoute looks healthy (providers up, routing profiles ok, no rate limit alerts) but the final answer is still wrong.
|
||||
فكرة بسيطة:
|
||||
|
||||
In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself.
|
||||
1. عندما تقوم بالتحقق من خلل في حسابك، قم بالقاطع:
|
||||
- مهمة المستخدم وطلبه
|
||||
- مجموعة الطريق أو المورد في OmniRoute
|
||||
- أي مؤتمر RAG في المراحل النهائية (المستندات المستردة، وأدوات الأدوات، وما إلى ذلك)
|
||||
2. قم بتخطيط الحادث لواحد أو من أرقام WFGY IssueMap (`رقم 1`...`رقم 16`).
|
||||
3. قم بتخزين الرقم في لوحة المعلومات الخاصة بك، أو دليل التشغيل، أو أداة التعقب بجوار سجلات OmniRoute.
|
||||
4. استخدم صفحة WFGY لتقرر ما إذا كنت تريد تغيير مكدس RAG أو المسترد أو استراتيجية التوجيه.
|
||||
|
||||
If you want a shared vocabulary to describe those failures you can use the WFGY ProblemMap, an external MIT license text resource that defines sixteen recurring RAG / LLM failure patterns. At a high level it covers:
|
||||
النص الكامل والوصفات الملموسة موجودة هنا (ترخيص معهد ماساتشوستس فارس، النص فقط):
|
||||
|
||||
- retrieval drift and broken context boundaries
|
||||
- empty or stale indexes and vector stores
|
||||
- embedding versus semantic mismatch
|
||||
- prompt assembly and context window issues
|
||||
- logic collapse and overconfident answers
|
||||
- long chain and agent coordination failures
|
||||
- multi agent memory and role drift
|
||||
- deployment and bootstrap ordering problems
|
||||
[الملف التمهيدي لخريطة مشاكل WFGY](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md)
|
||||
|
||||
The idea is simple:
|
||||
ستتجاهل هذا القسم إذا لم تسمح لـ RAG أو خطوط الأنابيب الخارجية خلف OmniRoute.---## Still Stuck?
|
||||
|
||||
1. When you investigate a bad response, capture:
|
||||
- user task and request
|
||||
- route or provider combo in OmniRoute
|
||||
- any RAG context used downstream (retrieved documents, tool calls, etc)
|
||||
2. Map the incident to one or two WFGY ProblemMap numbers (`No.1` … `No.16`).
|
||||
3. Store the number in your own dashboard, runbook, or incident tracker next to the OmniRoute logs.
|
||||
4. Use the corresponding WFGY page to decide whether you need to change your RAG stack, retriever, or routing strategy.
|
||||
|
||||
Full text and concrete recipes live here (MIT license, text only):
|
||||
|
||||
[WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md)
|
||||
|
||||
You can ignore this section if you do not run RAG or agent pipelines behind OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Still Stuck?
|
||||
|
||||
- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Architecture**: See [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) for internal details
|
||||
- **API Reference**: See [`docs/API_REFERENCE.md`](API_REFERENCE.md) for all endpoints
|
||||
- **Health Dashboard**: Check **Dashboard → Health** for real-time system status
|
||||
- **Translator**: Use **Dashboard → Translator** to debug format issues
|
||||
-**مشكلات GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**الهندسة الداخلية**: راجع [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) للحصول على التفاصيل -**مرجع واجهة برمجة التطبيقات**: راجع [`docs/API_REFERENCE.md`](API_REFERENCE.md) -**لوحة معلومات الصحة**: التحقق من**معلومات اللوحة ← صحة**معرفة النظام في الوقت الفعلي -**المترجم**: استخدم**لوحة المعلومات ← المترجم**ل التصحيح المناسب لك
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,39 @@
|
||||
# OmniRoute — Deployment Guide on VM with Cloudflare (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/VM_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/VM_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/VM_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/VM_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/VM_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/VM_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/VM_DEPLOYMENT_GUIDE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/VM_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/VM_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/VM_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/VM_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/VM_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/VM_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
|
||||
الدليل الكامل لـ OmniRoute وتكوينه على VM (VPS) مع المجال المُدار عبر Cloudflare.---## Prerequisites
|
||||
|
||||
---
|
||||
| حرق | الحد | موصى به |
|
||||
| -------------------------- | -------------------------------- | -------------------------------- |
|
||||
| **وحدة المعالجة المركزية** | 1 وحدة المعالجة المركزية الرقمية | 2 وحدة المعالجة المركزية الرقمية |
|
||||
| **ذاكرة الوصول العشوائي** | 1 جيجا | 2 جيجا |
|
||||
| **القرص** | 10 جيجا اس اس دي | 25 جيجا اس دي |
|
||||
| **نظام التشغيل** | أوبونتو 22.04 LTS | أوبونتو 24.04 LTS |
|
||||
| **المجال** | مسجل في Cloudflare | — |
|
||||
| **عامل ميناء** | محرك دوكر 24+ | عامل ميناء 27+ |
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Item | Minimum | Recommended |
|
||||
| ---------- | ------------------------ | ---------------- |
|
||||
| **CPU** | 1 vCPU | 2 vCPU |
|
||||
| **RAM** | 1 GB | 2 GB |
|
||||
| **Disk** | 10 GB SSD | 25 GB SSD |
|
||||
| **OS** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|
||||
| **Domain** | Registered on Cloudflare | — |
|
||||
| **Docker** | Docker Engine 24+ | Docker 27+ |
|
||||
|
||||
**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
|
||||
|
||||
---
|
||||
|
||||
## 1. Configure the VM
|
||||
**المزودون الذين تم اختبارهم**: Akamai (Linode)، DigitalOcean، Vultr، Hetzner، AWS Lightsail.---## 1. Configure the VM
|
||||
|
||||
### 1.1 Create the instance
|
||||
|
||||
On your preferred VPS provider:
|
||||
على موفر VPS المفضل لديك:
|
||||
|
||||
- Choose Ubuntu 24.04 LTS
|
||||
- Select the minimum plan (1 vCPU / 1 GB RAM)
|
||||
- Set a strong root password or configure SSH key
|
||||
- Note the **public IP** (e.g., `203.0.113.10`)
|
||||
- اختر Ubuntu 24.04 LTS
|
||||
-تحديد الحد الأدنى للخطة (1 vCPU / 1 جيجابايت من ذاكرة الوصول العشوائي)
|
||||
- قم بتواجد كلمة مرور جذر قوية أو قم بتكوين مفتاح SSH
|
||||
- ملحوظة**عنوان IP العام**(على سبيل المثال، `203.0.113.10`)### 1.2 الاتصال عبر SSH```bash
|
||||
ssh root@203.0.113.10
|
||||
|
||||
### 1.2 Connect via SSH
|
||||
|
||||
```bash
|
||||
ssh root@203.0.113.10
|
||||
```
|
||||
````
|
||||
|
||||
### 1.3 Update the system
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
````
|
||||
|
||||
### 1.4 Install Docker
|
||||
|
||||
@@ -78,11 +67,7 @@ ufw allow 443/tcp # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
> **Tip**: For maximum security, restrict ports 80 and 443 to Cloudflare IPs only. See the [Advanced Security](#advanced-security) section.
|
||||
|
||||
---
|
||||
|
||||
## 2. Install OmniRoute
|
||||
> **نصيحة**: للحصول على الحد الأقصى من الأمان، يجب بتقييد المنفذين 80 و443 بناوين Cloudflare IP فقط. راجع قسم [الأمان المتقدم](#الأمن المتقدم).---## 2. Install OmniRoute
|
||||
|
||||
### 2.1 Create configuration directory
|
||||
|
||||
@@ -122,126 +107,118 @@ NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
|
||||
EOF
|
||||
```
|
||||
|
||||
> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
|
||||
|
||||
### 2.3 Start the container
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
> ⚠️**هام**: أنشئ مفاتيح سرية فريدة! استخدم "openssl rand -hex 32" لكل مفتاح.### 2.3 ابدأ الحاوية```bash
|
||||
> docker pull diegosouzapw/omniroute:latest
|
||||
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
|
||||
````
|
||||
|
||||
### 2.4 Verify that it is running
|
||||
|
||||
```bash
|
||||
docker ps | grep omniroute
|
||||
docker logs omniroute --tail 20
|
||||
```
|
||||
````
|
||||
|
||||
It should display: `[DB] SQLite database ready` and `listening on port 20128`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Configure nginx (Reverse Proxy)
|
||||
يجب أن يتم تعرض: "قاعدة بيانات SQLite [DB] جاهزة" و"الاشتراك في منفذ 20128".---## 3. Configure nginx (Reverse Proxy)
|
||||
|
||||
### 3.1 Generate SSL certificate (Cloudflare Origin)
|
||||
|
||||
In the Cloudflare dashboard:
|
||||
في لوحة معلومات Cloudflare:
|
||||
|
||||
1. Go to **SSL/TLS → Origin Server**
|
||||
2. Click **Create Certificate**
|
||||
3. Keep the defaults (15 years, \*.yourdomain.com)
|
||||
4. Copy the **Origin Certificate** and the **Private Key**
|
||||
1. انتقل إلى**SSL/TLS → الخادم الأصلي**
|
||||
2.نقر**إنشاء شهادة**
|
||||
2. استخدم الإعدادات الافتراضية (15 عامًا، \*.yourdomain.com)
|
||||
4.انسخ**شهادة المنشأ**و**المفتاح الخاص**```bash
|
||||
mkdir -p /etc/nginx/ssl
|
||||
|
||||
```bash
|
||||
mkdir -p /etc/nginx/ssl
|
||||
# لصق الشهادة
|
||||
|
||||
# Paste the certificate
|
||||
nano /etc/nginx/ssl/origin.crt
|
||||
نانو /etc/nginx/ssl/origin.crt
|
||||
|
||||
# Paste the private key
|
||||
nano /etc/nginx/ssl/origin.key
|
||||
# الصق المفتاح الخاص
|
||||
|
||||
chmod 600 /etc/nginx/ssl/origin.key
|
||||
```
|
||||
نانو /etc/nginx/ssl/origin.key
|
||||
|
||||
chmod 600 /etc/nginx/ssl/origin.key```
|
||||
|
||||
### 3.2 Nginx Configuration
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
|
||||
# Default server — blocks direct access via IP
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
````bash
|
||||
cat > /etc/nginx/sites-available/omniroute << 'NGINX'
|
||||
# الخادم الافتراضي - يمنع الوصول المباشر عبر IP
|
||||
الخادم {
|
||||
الاستماع 80 default_server؛
|
||||
الاستماع [::]:80 default_server؛
|
||||
الاستماع 443 SSL default_server؛
|
||||
استمع [::]:443 ssl default_server؛
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
server_name _;
|
||||
return 444;
|
||||
اسم الخادم _;
|
||||
العودة 444؛
|
||||
}
|
||||
|
||||
# OmniRoute — HTTPS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name llms.yourdomain.com; # Change to your domain
|
||||
# OmniRoute - HTTPS
|
||||
الخادم {
|
||||
الاستماع 443 SSL؛
|
||||
استمع [::]:443 ssl;
|
||||
اسم الخادم llms.yourdomain.com; # التغيير إلى المجال الخاص بك
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
client_max_body_size 100M;
|
||||
Client_max_body_size 100M؛
|
||||
|
||||
location / {
|
||||
الموقع / {
|
||||
proxy_pass http://127.0.0.1:20128;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header المضيف $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header مخطط X-Forwarded-Proto $;
|
||||
|
||||
# WebSocket support
|
||||
# دعم ويبسوكيت
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection “upgrade”;
|
||||
ترقية proxy_set_header $http_upgrade;
|
||||
اتصال proxy_set_header "ترقية"؛
|
||||
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
# SSE (الأحداث المرسلة من الخادم) - تدفق استجابات الذكاء الاصطناعي
|
||||
proxy_buffering معطل؛
|
||||
proxy_cache معطل؛
|
||||
proxy_read_timeout 600s؛
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTP → HTTPS redirect
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name llms.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
# HTTP → إعادة توجيه HTTPS
|
||||
الخادم {
|
||||
استمع 80؛
|
||||
استمع [::]:80;
|
||||
اسم الخادم llms.yourdomain.com;
|
||||
إرجاع 301 https://$server_name$request_uri;
|
||||
}
|
||||
NGINX
|
||||
```
|
||||
نجينكس```
|
||||
|
||||
### 3.3 Enable and Test
|
||||
حافظ على توافق مهلات دفق الوكيل العكسي مع vars env لمهلة OmniRoute. إذا رفعت
|
||||
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`، ارفع `proxy_read_timeout` / `proxy_send_timeout`
|
||||
فوق نفس العتبة.### 3.3 Enable and Test
|
||||
|
||||
```bash
|
||||
# Remove default configuration
|
||||
# إزالة التكوين الافتراضي
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Enable OmniRoute
|
||||
# تمكين OmniRoute
|
||||
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
|
||||
|
||||
# Test and reload
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
# اختبار وإعادة تحميل
|
||||
nginx -t && systemctl إعادة تحميل nginx```
|
||||
|
||||
---
|
||||
|
||||
@@ -249,30 +226,25 @@ nginx -t && systemctl reload nginx
|
||||
|
||||
### 4.1 Add DNS record
|
||||
|
||||
In the Cloudflare dashboard → DNS:
|
||||
في لوحة معلومات Cloudflare → DNS:
|
||||
|
||||
| Type | Name | Content | Proxy |
|
||||
| اكتب | الاسم | المحتوى | الوكيل |
|
||||
| ---- | ------ | ---------------------- | ---------- |
|
||||
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
|
||||
| أ | ``للم`` | `203.0.113.10` (VM IP) | ✅ توكيل |### 4.2 Configure SSL
|
||||
|
||||
### 4.2 Configure SSL
|
||||
ضمن**SSL/TLS → نظرة عامة**:
|
||||
|
||||
Under **SSL/TLS → Overview**:
|
||||
- الوضع:**كامل (صارم)**
|
||||
|
||||
- Mode: **Full (Strict)**
|
||||
ضمن**SSL/TLS → شهادات الحافة**:
|
||||
|
||||
Under **SSL/TLS → Edge Certificates**:
|
||||
|
||||
- Always Use HTTPS: ✅ On
|
||||
- Minimum TLS Version: TLS 1.2
|
||||
- Automatic HTTPS Rewrites: ✅ On
|
||||
|
||||
### 4.3 Testing
|
||||
- استخدم HTTPS دائمًا: ✅ قيد التشغيل
|
||||
- الحد الأدنى لإصدار TLS: TLS 1.2
|
||||
- إعادة كتابة HTTPS تلقائيًا: ✅ تشغيل### 4.3 Testing
|
||||
|
||||
```bash
|
||||
curl -sI https://llms.seudominio.com/health
|
||||
# Should return HTTP/2 200
|
||||
```
|
||||
حليقة -sI https://llms.seudominio.com/health
|
||||
# يجب أن يُرجع HTTP/2 200```
|
||||
|
||||
---
|
||||
|
||||
@@ -281,41 +253,37 @@ curl -sI https://llms.seudominio.com/health
|
||||
### Upgrade to a new version
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
docker stop omniroute && docker rm omniroute
|
||||
docker run -d --name omniroute --restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
عامل ميناء سحب diegosouzapw/omniroute:latest
|
||||
عامل ميناء توقف omniroute && docker rm omniroute
|
||||
تشغيل عامل الإرساء -d --اسم المسار الشامل --إعادة التشغيل ما لم يتم إيقافه \
|
||||
--env-ملف /opt/omniroute/.env \
|
||||
-ص20128:20128\
|
||||
-v بيانات المسار الشامل:/app/data \
|
||||
diegosouzapw/omniroute:latest```
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
docker logs -f omniroute # Real-time stream
|
||||
docker logs omniroute --tail 50 # Last 50 lines
|
||||
```
|
||||
سجلات عامل الإرساء -f omniroute # البث في الوقت الفعلي
|
||||
سجلات عامل الإرساء في كل الاتجاهات --tail 50 # آخر 50 سطرًا```
|
||||
|
||||
### Manual database backup
|
||||
|
||||
```bash
|
||||
# Copy data from the volume to the host
|
||||
# انسخ البيانات من المجلد إلى المضيف
|
||||
docker cp omniroute:/app/data ./backup-$(date +%F)
|
||||
|
||||
# Or compress the entire volume
|
||||
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/omniroute-data-$(date +%F).tar.gz /data
|
||||
```
|
||||
# أو ضغط الحجم بأكمله
|
||||
تشغيل عامل الميناء --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
جبال الألب القطران czf /backup/omniroute-data-$(date +%F).tar.gz /data```
|
||||
|
||||
### Restore from backup
|
||||
|
||||
```bash
|
||||
docker stop omniroute
|
||||
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
alpine sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
|
||||
docker start omniroute
|
||||
```
|
||||
توقف عامل الإرساء في كل اتجاه
|
||||
تشغيل عامل الميناء --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
جبال الألب sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
|
||||
عامل الإرساء يبدأ في كل اتجاه```
|
||||
|
||||
---
|
||||
|
||||
@@ -324,8 +292,8 @@ docker start omniroute
|
||||
### Restrict nginx to Cloudflare IPs
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
|
||||
# Cloudflare IPv4 ranges — update periodically
|
||||
cat > /etc/nginx/cloudflare-ips.conf << 'CF'
|
||||
# نطاقات Cloudflare IPv4 - يتم تحديثها بشكل دوري
|
||||
# https://www.cloudflare.com/ips-v4/
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
@@ -343,14 +311,11 @@ set_real_ip_from 104.24.0.0/14;
|
||||
set_real_ip_from 172.64.0.0/13;
|
||||
set_real_ip_from 131.0.72.0/22;
|
||||
real_ip_header CF-Connecting-IP;
|
||||
CF
|
||||
```
|
||||
قوات التحالف```
|
||||
|
||||
Add the following to `nginx.conf` inside the `http {}` block:
|
||||
|
||||
```nginx
|
||||
أضف ما يلي إلى `nginx.conf` داخل الكتلة `http {}`:```nginx
|
||||
include /etc/nginx/cloudflare-ips.conf;
|
||||
```
|
||||
````
|
||||
|
||||
### Install fail2ban
|
||||
|
||||
@@ -379,25 +344,22 @@ netfilter-persistent save
|
||||
|
||||
## 7. Deploy to Cloudflare Workers (Optional)
|
||||
|
||||
For remote access via Cloudflare Workers (without exposing the VM directly):
|
||||
للوصول بعد عبر Cloudflare Workers (دون الكشف عن الجهاز الافتراضي مباشرة):```bash
|
||||
|
||||
# في المستودع المحلي
|
||||
|
||||
```bash
|
||||
# In the local repository
|
||||
cd omnirouteCloud
|
||||
npm install
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
تثبيت npm
|
||||
تسجيل دخول رانجلر npx
|
||||
نشر رانجلر npx```
|
||||
|
||||
See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
|
||||
---
|
||||
راجع الوثائق الكاملة على [omnirouteCloud/README.md](../omnirouteCloud/README.md).---
|
||||
|
||||
## Port Summary
|
||||
|
||||
| Port | Service | Access |
|
||||
| ----- | ----------- | -------------------------- |
|
||||
| 22 | SSH | Public (with fail2ban) |
|
||||
| 80 | nginx HTTP | Redirect → HTTPS |
|
||||
| 443 | nginx HTTPS | Via Cloudflare Proxy |
|
||||
| 20128 | OmniRoute | Localhost only (via nginx) |
|
||||
| ميناء | الخدمة | الوصول |
|
||||
| ----- | ------------- | ----------------------------- |
|
||||
| 22 | سش | عام (مع Fail2ban) |
|
||||
| 80 | إنجينكس HTTP | إعادة التوجيه → HTTPS |
|
||||
| 443 | إنجينكس HTTPS | عبر وكيل Cloudflare |
|
||||
| 20128 | أومنيروتي | المضيف المحلي فقط (عبر nginx) |
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
# OmniRoute A2A Server (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../../../src/lib/a2a/README.md) · 🇪🇸 [es](../../../../es/src/lib/a2a/README.md) · 🇫🇷 [fr](../../../../fr/src/lib/a2a/README.md) · 🇩🇪 [de](../../../../de/src/lib/a2a/README.md) · 🇮🇹 [it](../../../../it/src/lib/a2a/README.md) · 🇷🇺 [ru](../../../../ru/src/lib/a2a/README.md) · 🇨🇳 [zh-CN](../../../../zh-CN/src/lib/a2a/README.md) · 🇯🇵 [ja](../../../../ja/src/lib/a2a/README.md) · 🇰🇷 [ko](../../../../ko/src/lib/a2a/README.md) · 🇸🇦 [ar](../../../../ar/src/lib/a2a/README.md) · 🇮🇳 [in](../../../../in/src/lib/a2a/README.md) · 🇹🇭 [th](../../../../th/src/lib/a2a/README.md) · 🇻🇳 [vi](../../../../vi/src/lib/a2a/README.md) · 🇮🇩 [id](../../../../id/src/lib/a2a/README.md) · 🇲🇾 [ms](../../../../ms/src/lib/a2a/README.md) · 🇳🇱 [nl](../../../../nl/src/lib/a2a/README.md) · 🇵🇱 [pl](../../../../pl/src/lib/a2a/README.md) · 🇸🇪 [sv](../../../../sv/src/lib/a2a/README.md) · 🇳🇴 [no](../../../../no/src/lib/a2a/README.md) · 🇩🇰 [da](../../../../da/src/lib/a2a/README.md) · 🇫🇮 [fi](../../../../fi/src/lib/a2a/README.md) · 🇵🇹 [pt](../../../../pt/src/lib/a2a/README.md) · 🇷🇴 [ro](../../../../ro/src/lib/a2a/README.md) · 🇭🇺 [hu](../../../../hu/src/lib/a2a/README.md) · 🇧🇬 [bg](../../../../bg/src/lib/a2a/README.md) · 🇸🇰 [sk](../../../../sk/src/lib/a2a/README.md) · 🇺🇦 [uk-UA](../../../../uk-UA/src/lib/a2a/README.md) · 🇮🇱 [he](../../../../he/src/lib/a2a/README.md) · 🇵🇭 [phi](../../../../phi/src/lib/a2a/README.md) · 🇧🇷 [pt-BR](../../../../pt-BR/src/lib/a2a/README.md) · 🇨🇿 [cs](../../../../cs/src/lib/a2a/README.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../../../src/lib/a2a/README.md) · 🇪🇸 [es](../../../../es/src/lib/a2a/README.md) · 🇫🇷 [fr](../../../../fr/src/lib/a2a/README.md) · 🇩🇪 [de](../../../../de/src/lib/a2a/README.md) · 🇮🇹 [it](../../../../it/src/lib/a2a/README.md) · 🇷🇺 [ru](../../../../ru/src/lib/a2a/README.md) · 🇨🇳 [zh-CN](../../../../zh-CN/src/lib/a2a/README.md) · 🇯🇵 [ja](../../../../ja/src/lib/a2a/README.md) · 🇰🇷 [ko](../../../../ko/src/lib/a2a/README.md) · 🇸🇦 [ar](../../../../ar/src/lib/a2a/README.md) · 🇮🇳 [hi](../../../../hi/src/lib/a2a/README.md) · 🇮🇳 [in](../../../../in/src/lib/a2a/README.md) · 🇹🇭 [th](../../../../th/src/lib/a2a/README.md) · 🇻🇳 [vi](../../../../vi/src/lib/a2a/README.md) · 🇮🇩 [id](../../../../id/src/lib/a2a/README.md) · 🇲🇾 [ms](../../../../ms/src/lib/a2a/README.md) · 🇳🇱 [nl](../../../../nl/src/lib/a2a/README.md) · 🇵🇱 [pl](../../../../pl/src/lib/a2a/README.md) · 🇸🇪 [sv](../../../../sv/src/lib/a2a/README.md) · 🇳🇴 [no](../../../../no/src/lib/a2a/README.md) · 🇩🇰 [da](../../../../da/src/lib/a2a/README.md) · 🇫🇮 [fi](../../../../fi/src/lib/a2a/README.md) · 🇵🇹 [pt](../../../../pt/src/lib/a2a/README.md) · 🇷🇴 [ro](../../../../ro/src/lib/a2a/README.md) · 🇭🇺 [hu](../../../../hu/src/lib/a2a/README.md) · 🇧🇬 [bg](../../../../bg/src/lib/a2a/README.md) · 🇸🇰 [sk](../../../../sk/src/lib/a2a/README.md) · 🇺🇦 [uk-UA](../../../../uk-UA/src/lib/a2a/README.md) · 🇮🇱 [he](../../../../he/src/lib/a2a/README.md) · 🇵🇭 [phi](../../../../phi/src/lib/a2a/README.md) · 🇧🇷 [pt-BR](../../../../pt-BR/src/lib/a2a/README.md) · 🇨🇿 [cs](../../../../cs/src/lib/a2a/README.md) · 🇹🇷 [tr](../../../../tr/src/lib/a2a/README.md)
|
||||
|
||||
---
|
||||
|
||||
> **Agent-to-Agent Protocol v0.3** — Enables any AI agent to use OmniRoute as an intelligent routing agent via JSON-RPC 2.0.
|
||||
> **Agent-to-Agent Protocol v0.3**— يتزايد أي وكيل AI من استخدام OmniRoute كوكيل توجيه ذكي عبر JSON-RPC 2.0.
|
||||
|
||||
The A2A Server exposes OmniRoute as a **first-class agent** that other agents can discover, delegate tasks to, and collaborate with using the [A2A Protocol](https://google.github.io/A2A/).
|
||||
|
||||
---
|
||||
|
||||
## الهندسة
|
||||
يعرض مضيف A2A OmniRoute**وكيلًا من الدرجة الأولى**يمكن لوكلاء الاكتشافات الأخرى وطلب الاتصال به باستخدام [بروتوكول A2A](https://google.github.io/A2A/).---## الهندسة
|
||||
|
||||
```
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
@@ -43,52 +39,48 @@ The A2A Server exposes OmniRoute as a **first-class agent** that other agents ca
|
||||
|
||||
### Agent Discovery
|
||||
|
||||
Every A2A-compatible agent exposes an **Agent Card** at `/.well-known/agent.json`:
|
||||
يعرض كل وكيل متوافق مع A2A**بطاقة الوكيل**على `/.well-known/agent.json`:`bash
|
||||
حليقة http://localhost:20128/.well-known/agent.json`
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**إجابة:**```json
|
||||
{
|
||||
"name": "OmniRoute",
|
||||
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
|
||||
"url": "http://localhost:20128/a2a",
|
||||
"version": "1.8.1",
|
||||
"capabilities": {
|
||||
"streaming": true,
|
||||
"pushNotifications": false
|
||||
},
|
||||
"skills": [
|
||||
{
|
||||
"id": "smart-routing",
|
||||
"name": "Smart Routing",
|
||||
"description": "Routes prompts through OmniRoute intelligent pipeline",
|
||||
"tags": ["routing", "llm", "multi-provider", "cost-optimization"],
|
||||
"examples": [
|
||||
"Write a hello world in Python",
|
||||
"Explain quantum computing using the cheapest provider"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "quota-management",
|
||||
"name": "Quota Management",
|
||||
"description": "Natural-language queries about provider quotas",
|
||||
"tags": ["quota", "analytics", "cost"],
|
||||
"examples": [
|
||||
"Which provider has the most quota remaining?",
|
||||
"Suggest a free combo for coding"
|
||||
]
|
||||
}
|
||||
],
|
||||
"authentication": {
|
||||
"schemes": ["bearer"],
|
||||
"apiKeyHeader": "Authorization"
|
||||
}
|
||||
"name": "OmniRoute",
|
||||
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
|
||||
"url": "http://localhost:20128/a2a",
|
||||
"version": "1.8.1",
|
||||
"capabilities": {
|
||||
"streaming": true,
|
||||
"pushNotifications": false
|
||||
},
|
||||
"skills": [
|
||||
{
|
||||
"id": "smart-routing",
|
||||
"name": "Smart Routing",
|
||||
"description": "Routes prompts through OmniRoute intelligent pipeline",
|
||||
"tags": ["routing", "llm", "multi-provider", "cost-optimization"],
|
||||
"examples": [
|
||||
"Write a hello world in Python",
|
||||
"Explain quantum computing using the cheapest provider"
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "quota-management",
|
||||
"name": "Quota Management",
|
||||
"description": "Natural-language queries about provider quotas",
|
||||
"tags": ["quota", "analytics", "cost"],
|
||||
"examples": [
|
||||
"Which provider has the most quota remaining?",
|
||||
"Suggest a free combo for coding"
|
||||
]
|
||||
}
|
||||
```
|
||||
],
|
||||
"authentication": {
|
||||
"schemes": ["bearer"],
|
||||
"apiKeyHeader": "Authorization"
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -96,27 +88,22 @@ curl http://localhost:20128/.well-known/agent.json
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Send a message to a skill and receive the complete response.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
أرسل رسالة إلى إحدى المهارات واحصل على الرد الكامل.```bash
|
||||
حليقة -X POST http://localhost:20128/a2a \
|
||||
-H "نوع المحتوى: application/json" \
|
||||
-H "التفويض: حامل YOUR_KEY" \
|
||||
-د '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a Python hello world"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
"المعرف": "1"،
|
||||
"الطريقة": "رسالة/إرسال"،
|
||||
"المعلمات": {
|
||||
"المهارة": "التوجيه الذكي"،
|
||||
"messages": [{"role": "user", "content": "اكتب عالم بايثون المرحب"}],
|
||||
"بيانات التعريف": {"model": "auto"، "combo": "الترميز السريع"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
}'```
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**إجابة:**```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
@@ -133,36 +120,32 @@ curl -X POST http://localhost:20128/a2a \
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
### `message/stream` — SSE Streaming
|
||||
|
||||
Same as `message/send` but returns Server-Sent Events for real-time streaming.
|
||||
|
||||
```bash
|
||||
curl -N -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
نفس `الرسالة/الإرسال` ولكنها تُرجع الأحداث المرسلة من العميل للبث في الوقت الحقيقي.`bash
|
||||
حليقة -N -X POST http://localhost:20128/a2a \
|
||||
-H "نوع المحتوى: application/json" \
|
||||
-H "التفويض: حامل YOUR_KEY" \
|
||||
-د '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
"المعرف": "1"،
|
||||
"الطريقة": "رسالة/دفق"،
|
||||
"المعلمات": {
|
||||
"المهارة": "التوجيه الذكي"،
|
||||
"messages": [{"role": "user", "content": "شرح الحوسبة الكمومية"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
}'`
|
||||
|
||||
**SSE Events:**
|
||||
|
||||
```
|
||||
**أحداث SSE:**```
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"Quantum computing..."}}}
|
||||
|
||||
: heartbeat 2026-03-04T21:00:00Z
|
||||
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### `tasks/get` — Query Task Status
|
||||
|
||||
@@ -171,7 +154,7 @@ curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
````
|
||||
|
||||
### `tasks/cancel` — Cancel a Running Task
|
||||
|
||||
@@ -188,42 +171,36 @@ curl -X POST http://localhost:20128/a2a \
|
||||
|
||||
### `smart-routing`
|
||||
|
||||
Routes prompts through OmniRoute's intelligent pipeline with full observability.
|
||||
تطالب المسارات عبر خط الأنابيب OmniRoute الذكي مع إمكانية المراقبة الكاملة.
|
||||
|
||||
**Parameters (in `metadata`):**
|
||||
**المعلمات (في `البيانات الوصفية`):**
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | -------- | ------------ | ---------------------------------------------------------------------------------------- |
|
||||
| `model` | `string` | `"auto"` | Target model (e.g., `claude-sonnet-4`, `gpt-4o`, `auto`) |
|
||||
| `combo` | `string` | active combo | Specific combo to route through |
|
||||
| `budget` | `number` | none | Maximum cost in USD for this request |
|
||||
| `role` | `string` | none | Task role hint: `coding`, `review`, `planning`, `analysis`, `debugging`, `documentation` |
|
||||
| المعلمة | اكتب | افتراضي | الوصف |
|
||||
| ---------------- | --------- | ------------------ | ----------------------------------------------------------------------------- |
|
||||
| `نموذج` | "السلسلة" | `"تلقائي"` | النموذج المستهدف (على سبيل المثال، `clude-sonnet-4`، `gpt-4o`، `auto`) |
|
||||
| `التحرير والسرد` | "السلسلة" | التحرير والسرد لكم | التحرير والسرد للتوجيه من خلال |
|
||||
| `الميزانية` | `الرقم` | لا شيء | الحد الأقصى للتكلفة بالدولار الأمريكي هذا الطلب |
|
||||
| `دور` | "السلسلة" | لا شيء | تلميح مهم: `التميز`، `المراجعة`، `التخطيط`، `التحليل`، `تصحيح سبب`، `التوثيق` |
|
||||
|
||||
**Returns:**
|
||||
**المرتجعات:**
|
||||
|
||||
| Field | Description |
|
||||
| ------------------------------ | --------------------------------------------------------- |
|
||||
| `artifacts[].content` | The LLM response text |
|
||||
| `metadata.routing_explanation` | Human-readable explanation of routing decision |
|
||||
| `metadata.cost_envelope` | Estimated vs actual cost with currency |
|
||||
| `metadata.resilience_trace` | Array of events (primary_selected, fallback_needed, etc.) |
|
||||
| `metadata.policy_verdict` | Whether the request was allowed and why |
|
||||
| | الوصف |
|
||||
| ------------------------------ | ------------------------------------------------------------------------ | ----------------- |
|
||||
| `المصنوعات[].content` | نصرد LLM |
|
||||
| `metadata.routing_explanation` | شرح مفهوم لقرار التوجيه |
|
||||
| `metadata.cost_envelope` | التكلفة المقدرة مقابل تكلفة التكلفة للعملة |
|
||||
| `metadata.resilience_trace` | مصفوفة من الأحداث (تم تحديدها بشكل أساسي، والمطلوبة بديلاً، وما إلى ذلك) |
|
||||
| `metadata.policy_verdict` | ما إذا كان ائداً لها لسبب | ### `إدارة الحصص` |
|
||||
|
||||
### `quota-management`
|
||||
يجيب على استفسارات اللغة الطبيعية حول حصص الموفرين.
|
||||
|
||||
Answers natural-language queries about provider quotas.
|
||||
**أنواع اتفق (المنتهية من محتوى الرسالة):**
|
||||
|
||||
**Query types (inferred from message content):**
|
||||
|
||||
| Query Pattern | Response Type |
|
||||
| ---------------------------------------------- | -------------------------------------------------------- |
|
||||
| Contains `"ranking"`, `"most quota"`, `"best"` | Providers ranked by remaining quota |
|
||||
| Contains `"free"`, `"suggest"` | Lists free combos or suggests free-tier providers |
|
||||
| Default | Full quota summary with warnings for low-quota providers |
|
||||
|
||||
---
|
||||
|
||||
## Task Lifecycle
|
||||
| نمط | نوع المصدر |
|
||||
| ------------------------------------------------- | ----------------------------------------- | -------------------- |
|
||||
| يحتوي على `"التصنيف"`، `"الأكثر حصة"`، `"الأفضل"` | تم ترتيب مقدمي الخدمة حسب الحصص النهائية |
|
||||
| يحتوي على `"مجاني"`، `"اقتراح"` | يسرد المهرجانات أو المهرجانات المجانية |
|
||||
| افتراضي | ملخص كامل للحصص مع تحذيرات للحصص المنخفضة | ---## Task Lifecycle |
|
||||
|
||||
```
|
||||
submitted ──→ working ──→ completed
|
||||
@@ -231,21 +208,17 @@ submitted ──→ working ──→ completed
|
||||
──────────→ cancelled
|
||||
```
|
||||
|
||||
| State | Description |
|
||||
| ----------- | ----------------------------------------------------- |
|
||||
| `submitted` | Task created, queued for execution |
|
||||
| `working` | Skill handler is executing |
|
||||
| `completed` | Execution succeeded, artifacts available |
|
||||
| `failed` | Execution failed or task expired (TTL: 5 min default) |
|
||||
| `cancelled` | Cancelled by client via `tasks/cancel` |
|
||||
| الدولة | الوصف |
|
||||
| -------- | ------------------------------------------------------------ |
|
||||
| `مُقدم` | تم إنشاء المهمة، في قائمة الانتظار للتنفيذ |
|
||||
| `العمل` | معالج المهارة ينفذ |
|
||||
| `مكتملة` | البدء في التنفيذ، القطع الأثرية الصعبة |
|
||||
| `فشل` | فشل التنفيذ أو النهاية إلى النهاية (TTL: 5 بالضغط الافتراضي) |
|
||||
| `ملغاة` | تم الإلغاء من قبل العميل عبر `المهام/الإلغاء` |
|
||||
|
||||
- Terminal states: `completed`, `failed`, `cancelled` (no further transitions)
|
||||
- Expired tasks in `submitted` or `working` are auto-marked as `failed`
|
||||
- Tasks are garbage-collected after 2× TTL
|
||||
|
||||
---
|
||||
|
||||
## Client Examples
|
||||
- حالات الوحدة الطرفية: `مكتملة`، `فشل`، `ملغى` (لم تحدث عمليات انتقال أخرى)
|
||||
- يتم وضع العلامة التجارية الجديدة على انتهاء الصلاحية في "المقدمة" أو "الجاري" على أنها "فاشلة".
|
||||
- يتم جمع المهام المهمة بعد 2 × TTL---## Client Examples
|
||||
|
||||
### Python — Orchestrator Agent
|
||||
|
||||
@@ -541,40 +514,33 @@ func main() {
|
||||
|
||||
### 🤖 Use Case 1: Multi-Agent Coding Pipeline
|
||||
|
||||
An orchestrator agent delegates code generation to OmniRoute, then passes the output to a review agent.
|
||||
يقوم وكيل منسق بتفويض إنشاء تعليمات الحظر إلى OmniRoute، ثم يقوم بتمرير الترخيص لوكيل التعديل.```python
|
||||
تعريف coding_pipeline (المهمة: str): # الخطوة 1: قم بإنشاء الكود عبر OmniRoute A2A
|
||||
code_result = a2a_send("التوجيه الذكي"، [
|
||||
{"role": "user"، "content": f"اكتب كود جودة الإنتاج: {task}"}
|
||||
]، البيانات الوصفية={"model": "auto"، "role": "coding"})
|
||||
كود = code_result["artifacts"][0]["content"]
|
||||
|
||||
```python
|
||||
def coding_pipeline(task: str):
|
||||
# Step 1: Generate code via OmniRoute A2A
|
||||
code_result = a2a_send("smart-routing", [
|
||||
{"role": "user", "content": f"Write production-quality code: {task}"}
|
||||
], metadata={"model": "auto", "role": "coding"})
|
||||
code = code_result["artifacts"][0]["content"]
|
||||
# الخطوة الثانية: قم بمراجعة الكود عبر OmniRoute A2A (نموذج مختلف)
|
||||
review_result = a2a_send("التوجيه الذكي"، [
|
||||
{"role": "user"، "content": f"راجع هذا الرمز بحثًا عن الأخطاء والتحسينات:\n\n{code}"}
|
||||
]، البيانات الوصفية={"model": "auto"، "role": "review"})
|
||||
المراجعة = review_result["artifacts"][0]["content"]
|
||||
|
||||
# Step 2: Review the code via OmniRoute A2A (different model)
|
||||
review_result = a2a_send("smart-routing", [
|
||||
{"role": "user", "content": f"Review this code for bugs and improvements:\n\n{code}"}
|
||||
], metadata={"model": "auto", "role": "review"})
|
||||
review = review_result["artifacts"][0]["content"]
|
||||
# الخطوة 3: التحقق من التكاليف
|
||||
print(f"تكلفة الكود: ${code_result['metadata']['cost_envelope']['actual']}")
|
||||
print(f"تكلفة المراجعة: ${review_result['metadata']['cost_envelope']['actual']}")
|
||||
|
||||
# Step 3: Check costs
|
||||
print(f"Code cost: ${code_result['metadata']['cost_envelope']['actual']}")
|
||||
print(f"Review cost: ${review_result['metadata']['cost_envelope']['actual']}")
|
||||
|
||||
return {"code": code, "review": review}
|
||||
```
|
||||
إرجاع {"كود": كود، "مراجعة": مراجعة}```
|
||||
|
||||
### 💡 Use Case 2: Quota-Aware Agent Swarm
|
||||
|
||||
Multiple agents share quota through OmniRoute, using the quota skill to coordinate.
|
||||
|
||||
```python
|
||||
async def quota_aware_agent(agent_name: str, task: str):
|
||||
# Check quota before starting
|
||||
quota = a2a_send("quota-management", [
|
||||
{"role": "user", "content": "Which provider has the most quota remaining?"}
|
||||
])
|
||||
print(f"[{agent_name}] {quota['artifacts'][0]['content']}")
|
||||
يقوم العديد من الوكلاء بمشاركة الحصص من خلال OmniRoute، وذلك باستخدام مهارة الحصص للتنسيق.```python
|
||||
async def quota_aware_agent(agent_name: str, task: str): # Check quota before starting
|
||||
quota = a2a_send("quota-management", [
|
||||
{"role": "user", "content": "Which provider has the most quota remaining?"}
|
||||
])
|
||||
print(f"[{agent_name}] {quota['artifacts'][0]['content']}")
|
||||
|
||||
# Send request with budget constraint
|
||||
result = a2a_send("smart-routing", [
|
||||
@@ -591,64 +557,60 @@ async def quota_aware_agent(agent_name: str, task: str):
|
||||
print(f"[{agent_name}] Free alternatives: {quota['artifacts'][0]['content']}")
|
||||
|
||||
return result
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### 📊 Use Case 3: Real-Time Streaming Dashboard
|
||||
|
||||
A monitoring agent streams responses and displays progress in real-time.
|
||||
|
||||
```typescript
|
||||
async function streamingDashboard(prompt: string) {
|
||||
const response = await fetch(`${BASE_URL}/a2a`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` },
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "dash-1",
|
||||
method: "message/stream",
|
||||
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
|
||||
يقوم بالمراقبة ببث الاستجابات ويعرض التقدم في الوقت الفعلي.```typescript
|
||||
وظيفة غير متزامنة StreamDashboard(prompt: string) {
|
||||
استجابة ثابتة = انتظار الجلب(`${BASE_URL}/a2a`, {
|
||||
الطريقة: "POST"،
|
||||
الرؤوس: { "نوع المحتوى": "application/json"، التفويض: `Bearer ${API_KEY}` }،
|
||||
الجسم: JSON.stringify({
|
||||
جسونربك: "2.0"،
|
||||
المعرف: "داش-1"،
|
||||
الطريقة: "رسالة/دفق"،
|
||||
المعلمات: { المهارة: "التوجيه الذكي"، الرسائل: [{ الدور: "المستخدم"، المحتوى: موجه }] }،
|
||||
}),
|
||||
});
|
||||
|
||||
let totalChunks = 0;
|
||||
const reader = response.body!.getReader();
|
||||
دع مجموع القطع = 0؛
|
||||
قارئ ثابت = استجابة. الجسم!.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
بينما (صحيح) {
|
||||
const { تم، القيمة } = انتظار Reader.read();
|
||||
إذا (تم) كسر؛
|
||||
|
||||
for (const line of decoder.decode(value).split("\n")) {
|
||||
if (line.startsWith("data: ")) {
|
||||
const event = JSON.parse(line.slice(6));
|
||||
const state = event.params.task.state;
|
||||
for (سطر ثابت من decoder.decode(value).split("\n")) {
|
||||
إذا (line.startsWith("البيانات:")) {
|
||||
حدث const = JSON.parse(line.slice(6));
|
||||
حالة ثابتة = Event.params.task.state;
|
||||
|
||||
if (state === "working" && event.params.chunk) {
|
||||
totalChunks++;
|
||||
process.stdout.write(
|
||||
`\r[Chunk ${totalChunks}] ${event.params.chunk.content.slice(0, 50)}...`
|
||||
إذا (الحالة === "العمل" && events.params.chunk) {
|
||||
TotalChunks++;
|
||||
عملية.stdout.write(
|
||||
`\r[قطعة ${totalChunks}] ${event.params.chunk.content.slice(0, 50)}...`
|
||||
);
|
||||
}
|
||||
if (state === "completed") {
|
||||
const meta = event.params.metadata;
|
||||
إذا (الحالة === "مكتملة") {
|
||||
const meta = events.params.metadata;
|
||||
console.log(
|
||||
`\n✅ Done | Cost: $${meta?.cost_envelope?.actual || 0} | Route: ${meta?.routing_explanation || "N/A"}`
|
||||
`\n ✅ تم | التكلفة: $${meta?.cost_envelope?.actual || 0} | الطريق: ${meta?.routing_explanation || "غير متوفر"}`
|
||||
);
|
||||
}
|
||||
if (state === "failed") {
|
||||
إذا (الحالة === "فشل") {
|
||||
console.error(`\n❌ Failed: ${event.params.metadata?.error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
}```
|
||||
|
||||
### 🔁 Use Case 4: Task Polling Pattern
|
||||
|
||||
For long-running tasks, poll the task status instead of waiting synchronously.
|
||||
|
||||
```python
|
||||
بالنسبة للمهام طويلة الأمد، قم باستقصاء حالة المهمة بدلاً من الانتظار بشكل متزامن.```python
|
||||
import time
|
||||
|
||||
def poll_task(task_id: str, timeout: int = 60):
|
||||
@@ -678,75 +640,64 @@ def poll_task(task_id: str, timeout: int = 60):
|
||||
"params": {"taskId": task_id},
|
||||
})
|
||||
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Constant | Meaning |
|
||||
| ------ | ------------------------ | ---------------------------------------- |
|
||||
| -32700 | — | Parse error (invalid JSON) |
|
||||
| -32600 | `INVALID_REQUEST` | Invalid JSON-RPC request or unauthorized |
|
||||
| -32601 | `METHOD_NOT_FOUND` | Unknown method or skill |
|
||||
| -32602 | `INVALID_PARAMS` | Missing or invalid parameters |
|
||||
| -32603 | `INTERNAL_ERROR` | Skill execution failed |
|
||||
| -32001 | `TASK_NOT_FOUND` | Task ID not found |
|
||||
| -32002 | `TASK_ALREADY_COMPLETED` | Cannot modify a completed task |
|
||||
| -32003 | `UNAUTHORIZED` | Invalid or missing API key |
|
||||
| -32004 | `BUDGET_EXCEEDED` | Request exceeds configured budget |
|
||||
| -32005 | `PROVIDER_UNAVAILABLE` | No available providers |
|
||||
| الكود | ثابت | معنى |
|
||||
| ------ | -------------------------- | --------------------------------- | -------------------- |
|
||||
| -32700 | — | خطأ في التحليل (JSON غير صالح) |
|
||||
| -32600 | `طلب_غير صالح` | طلب JSON-RPC غير صالح أو | غير مصرح به |
|
||||
| -32601 | `METHOD_NOT_FOUND` | طريقة أو مهارة غير معروفة |
|
||||
| -32602 | `INVALID_PARAMS` | معلمات مفقودة أو غير صالحة |
|
||||
| -32603 | `خطأ_داخلي` | فشل في تنفيذ المهارة |
|
||||
| -32001 | `مهمة_لم يتم العثور عليها` | لم يتم العثور على المفتاح الرئيسي |
|
||||
| -32002 | `المهمة_الجاهزة_مكتملة` | لا يمكن تعديل مهمة مكتملة |
|
||||
| -32003 | "غير مصرح به" | API الرئيسية غير صالحة أو مفقودة |
|
||||
| -32004 | `الميزانية_تجاوزت` | التجاوز المدى المكمل |
|
||||
| -32005 | `PROVIDER_UNAVAILABLE` | لا يوجد مقدمي خيارات الأسهم | ---## Authentication |
|
||||
|
||||
---
|
||||
تتطلب جميع الطلبات `/a2a` رمزًا مميزًا لحاملها عبر الرأس `الإعلان`:`
|
||||
التفويض: الحامل YOUR_OMNIROUTE_API_KEY`
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require a Bearer token via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server (`OMNIROUTE_API_KEY` is empty), authentication is bypassed.
|
||||
|
||||
---
|
||||
إذا لم يتم تكوين أي مفتاح API على الخادم (`OMNIROUTE_API_KEY` فارغ)، فسيتم تجاوز المصادقة.---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
src/lib/a2a/
|
||||
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
|
||||
├── taskExecution.ts # Generic task executor with state management
|
||||
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
|
||||
├── routingLogger.ts # Routing decision logger (stats, history, retention)
|
||||
└── skills/
|
||||
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
|
||||
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
|
||||
````
|
||||
سرك/ليب/a2a/
|
||||
├── TaskManager.ts # دورة حياة المهمة (إنشاء/تحديث/إلغاء/قائمة)، TTL، تنظيف
|
||||
├── TaskExecution.ts # منفذ المهام العامة مع إدارة الحالة
|
||||
├── Stream.ts # تنسيق دفق SSE، ونبضات القلب، وأحداث القطعة/الإكمال
|
||||
├── routingLogger.ts # مسجل قرار التوجيه (الإحصائيات والتاريخ والاحتفاظ)
|
||||
└── المهارات/
|
||||
├── SmartRouting.ts # مهارة التوجيه الذكي (الطرق عبر /v1/chat/completions)
|
||||
└── quotaManagement.ts # مهارة إدارة الحصص (استعلامات الحصص باللغة الطبيعية)
|
||||
|
||||
src/app/a2a/
|
||||
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
|
||||
سرك/التطبيق/a2a/
|
||||
└── Route.ts # معالج مسار واجهة برمجة التطبيقات Next.js (إرسال JSON-RPC 2.0)
|
||||
|
||||
open-sse/mcp-server/
|
||||
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
|
||||
```
|
||||
مفتوح-SSE/MCP-خادم/
|
||||
└── schemas/a2a.ts # مخططات Zod (AgentCard، Task، JSON-RPC، أحداث SSE)```
|
||||
|
||||
---
|
||||
|
||||
## Comparison: MCP vs A2A
|
||||
|
||||
| Feature | MCP Server | A2A Server |
|
||||
| ميزة | خادم MCP | خادم A2A |
|
||||
| ----------------- | ---------------------------- | ------------------------------------------------- |
|
||||
| **Protocol** | Model Context Protocol | Agent-to-Agent Protocol v0.3 |
|
||||
| **Transport** | stdio / HTTP | HTTP (JSON-RPC 2.0) |
|
||||
| **Discovery** | Tool listing via MCP | `/.well-known/agent.json` |
|
||||
| **Granularity** | 16 individual tools | 2 high-level skills |
|
||||
| **Best for** | IDE agents (Cursor, VS Code) | Multi-agent systems (LangChain, CrewAI) |
|
||||
| **Streaming** | Not supported | SSE via `message/stream` |
|
||||
| **Task tracking** | No | Full lifecycle (submitted → completed) |
|
||||
| **Observability** | Audit log per tool call | Cost envelope + resilience trace + policy verdict |
|
||||
|
||||
---
|
||||
|**البروتوكول**| بروتوكول السياق النموذجي | بروتوكول وكيل إلى وكيل v0.3 |
|
||||
|**النقل**| ستديو / HTTP | HTTP (JSON-RPC 2.0) |
|
||||
|**الاكتشاف**| قائمة الأدوات عبر MCP | `/.well-known/agent.json` |
|
||||
|**التفاصيل**| 16 أداة فردية | 2 مهارات عالية المستوى |
|
||||
|**الأفضل لـ**| وكلاء IDE (المؤشر، كود VS) | أنظمة متعددة الوكلاء (LangChain، CrewAI) |
|
||||
|**البث**| غير مدعوم | SSE عبر "الرسالة/الدفق" |
|
||||
|**تتبع المهام**| لا | دورة حياة كاملة (مقدمة → مكتملة) |
|
||||
|**الملاحظة**| سجل التدقيق لكل استدعاء أداة | مظروف التكلفة + تتبع المرونة + حكم السياسة |---
|
||||
|
||||
## الرخصة
|
||||
|
||||
Part of [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — MIT License.
|
||||
جزء من [OmniRoute](https://github.com/diegosouzapw/OmniRoute) - ترخيص معهد ماساتشوستس للتكنولوجيا.
|
||||
````
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,28 +1,19 @@
|
||||
# Contributing to OmniRoute (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [hi](../hi/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md) · 🇹🇷 [tr](../tr/CONTRIBUTING.md)
|
||||
|
||||
---
|
||||
|
||||
Thank you for your interest in contributing! This guide covers everything you need to get started.
|
||||
|
||||
---
|
||||
|
||||
## Development Setup
|
||||
Благодарим ви за интереса да допринесете! Това ръководство обхваща всичко необходимо, за да работи.---## Development Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
|
||||
- **npm** 10+
|
||||
- **Git**
|
||||
|
||||
### Clone & Install
|
||||
|
||||
```bash
|
||||
-**Node.js**>= 18 < 24 (препоръчително: 22 LTS) -**npm**10+ -**Git**### Клониране и инсталиране```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute
|
||||
npm install
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### Environment Variables
|
||||
|
||||
@@ -33,90 +24,74 @@ cp .env.example .env
|
||||
# Generate required secrets
|
||||
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
|
||||
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
|
||||
```
|
||||
````
|
||||
|
||||
Key variables for development:
|
||||
Ключови променливи за развитие:
|
||||
|
||||
| Variable | Development Default | Description |
|
||||
| ---------------------- | ------------------------ | --------------------- |
|
||||
| `PORT` | `20128` | Server port |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
|
||||
| `JWT_SECRET` | (generate above) | JWT signing secret |
|
||||
| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
|
||||
| `APP_LOG_LEVEL` | `info` | Log verbosity level |
|
||||
| Променлива | Разработка по подразбиране | Описание |
|
||||
| ---------------------- | -------------------------- | ------------------------------------------ | ---------------------- |
|
||||
| `ПОРТ` | „20128“ | Порт на сървъра |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Основен URL адрес за интерфейс |
|
||||
| `JWT_SECRET` | (генериране по-горе) | Тайна за подписване на JWT |
|
||||
| `ПЪРВОНАЧАЛНА_ПАРОЛА` | `CHANGEME` | Първа парола за влизане |
|
||||
| `APP_LOG_LEVEL` | `информация` | Ниво на подробност на регистрационния файл | ### Dashboard Settings |
|
||||
|
||||
### Dashboard Settings
|
||||
Таблото за управление предоставя UI превключватели за функции, които също могат да бъдат конфигурирани чрез променливи на средата:
|
||||
|
||||
The dashboard provides UI toggles for features that can also be configured via environment variables:
|
||||
| Задаване на местоположение | Превключване | Описание |
|
||||
| -------------------------- | ------------------------------- | --------------------------------------------------------------------------------- |
|
||||
| Настройки → Разширени | Режим на отстраняване на грешки | Активиране на регистрационните файлове на заявките за отстраняване на грешки (UI) |
|
||||
| Настройки → Общи | Видимост на страничната лента | Показване/скриване на секциите на страничната лента |
|
||||
|
||||
| Setting Location | Toggle | Description |
|
||||
| ------------------- | ------------------ | ------------------------------ |
|
||||
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
|
||||
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
|
||||
Тези настройки се запазват в базата данни и се запазват при рестартиране, като заменят настройките по подразбиране env var, когато са претърпени.### Running Locally```bash
|
||||
|
||||
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
|
||||
|
||||
### Running Locally
|
||||
|
||||
```bash
|
||||
# Development mode (hot reload)
|
||||
|
||||
npm run dev
|
||||
|
||||
# Production build
|
||||
|
||||
npm run build
|
||||
npm run start
|
||||
|
||||
# Common port configuration
|
||||
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
```
|
||||
|
||||
Default URLs:
|
||||
````
|
||||
|
||||
- **Dashboard**: `http://localhost:20128/dashboard`
|
||||
- **API**: `http://localhost:20128/v1`
|
||||
URL адреси по подразбиране:
|
||||
|
||||
---
|
||||
-**Табло за управление**: `http://localhost:20128/табло за управление`
|
||||
-**API**: `http://localhost:20128/v1`---## Git Workflow
|
||||
|
||||
## Git Workflow
|
||||
|
||||
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
|
||||
|
||||
```bash
|
||||
> ⚠️**НИКОГА не се включва директно с `main`.**Винаги използват разклонения на функции.```bash
|
||||
git checkout -b feat/your-feature-name
|
||||
# ... make changes ...
|
||||
git commit -m "feat: describe your change"
|
||||
# ... направи промени ...
|
||||
git commit -m "feat: опишете вашата промяна"
|
||||
git push -u origin feat/your-feature-name
|
||||
# Open a Pull Request on GitHub
|
||||
```
|
||||
# Отворете заявка за изтегляне в GitHub```
|
||||
|
||||
### Branch Naming
|
||||
|
||||
| Prefix | Purpose |
|
||||
| ----------- | ------------------------- |
|
||||
| `feat/` | New features |
|
||||
| `fix/` | Bug fixes |
|
||||
| `refactor/` | Code restructuring |
|
||||
| `docs/` | Documentation changes |
|
||||
| `test/` | Test additions/fixes |
|
||||
| `chore/` | Tooling, CI, dependencies |
|
||||
| Префикс | Цел |
|
||||
| ----------- | ------------------------ |
|
||||
| `подвиг/` | Нови функции |
|
||||
| `поправи/` | Поправки на грешки |
|
||||
| `рефактор/` | Преструктуриране на код |
|
||||
| `документи/` | Промени в документацията |
|
||||
| `тест/` | Тестови допълнения/поправки |
|
||||
| `скучна работа/` | Инструментална екипировка, CI, зависимости |### Commit Messages
|
||||
|
||||
### Commit Messages
|
||||
|
||||
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
||||
|
||||
```
|
||||
Следвайте [Конвенционални ангажименти](https://www.conventionalcommits.org/):```
|
||||
feat: add circuit breaker for provider calls
|
||||
fix: resolve JWT secret validation edge case
|
||||
docs: update SECURITY.md with PII protection
|
||||
test: add observability unit tests
|
||||
refactor(db): consolidate rate limit tables
|
||||
```
|
||||
````
|
||||
|
||||
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
|
||||
|
||||
---
|
||||
|
||||
## Running Tests
|
||||
Обхвати: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.---## Running Tests
|
||||
|
||||
```bash
|
||||
# All tests (unit + vitest + ecosystem + e2e)
|
||||
@@ -137,7 +112,7 @@ npm run test:protocols:e2e
|
||||
# Ecosystem compatibility tests
|
||||
npm run test:ecosystem
|
||||
|
||||
# Coverage (55% min statements/lines/functions; 60% branches)
|
||||
# Coverage (60% min statements/lines/functions/branches)
|
||||
npm run test:coverage
|
||||
npm run coverage:report
|
||||
|
||||
@@ -146,38 +121,35 @@ npm run lint
|
||||
npm run check
|
||||
```
|
||||
|
||||
Coverage notes:
|
||||
Бележки за покритието:
|
||||
|
||||
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
|
||||
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
|
||||
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
|
||||
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
|
||||
- `npm run test:coverage` измерва покритието на източника за тестови пакети на основната единица, изключвайки `tests/**` и включва `open-sse/**`
|
||||
- Заявките за изтегляне трябва да поддържат общата врата за покритие на**60% или по-висока**за отчети, линии, функции и клонове
|
||||
- Ако PR промени производствения код в `src/`, `open-sse/`, `electron/` или `bin/`, той трябва да добави или актуализира автоматизирани тестове в същия PR
|
||||
- `npm run coverage:report` отпечатва подробния отчетен файл по файл от последното изпълнение на покритието
|
||||
- `npm run test:coverage:legacy` запазва по-старата метрика за историческо сравнение
|
||||
- Вижте `docs/COVERAGE_PLAN.md` за поетапна пътна карта за подобряване на покритието### Pull Request Requirements
|
||||
|
||||
Current test status: **122 unit test files** covering:
|
||||
Преди да отворите или обедините PR:
|
||||
|
||||
- Provider translators and format conversion
|
||||
- Rate limiting, circuit breaker, and resilience
|
||||
- Semantic cache, idempotency, progress tracking
|
||||
- Database operations and schema (21 DB modules)
|
||||
- OAuth flows and authentication
|
||||
- API endpoint validation (Zod v4)
|
||||
- MCP server tools and scope enforcement
|
||||
- Memory and Skills systems
|
||||
- Стартирайте `npm run test:unit`
|
||||
- Стартирайте `npm run test:coverage`
|
||||
- Уверете се, че вратата за покритие остава на**60%+**за всички показатели
|
||||
- Включете променените или добавени тестови файлове в PR описанието при промяна на производствения код
|
||||
- Проверете резултатите от SonarQube на PR, когато тайните на проекта са конфигурирани в CI
|
||||
|
||||
---
|
||||
Текущо състояние на теста:**122 файла за единичен тест**, обхващащи:
|
||||
|
||||
## Code Style
|
||||
- Преводачи на доставчици и конвертиране на формати
|
||||
- Ограничаване на скоростта, прекъсвач и устойчивост
|
||||
- Семантичен кеш, идемпотентност, проследяване на напредъка
|
||||
- Операции с база данни и схема (21 DB модула)
|
||||
- OAuth потоци и удостоверяване
|
||||
- API валиден за крайни точки (Zod v4)
|
||||
- MCP сървърни инструменти и прилагане на обхват
|
||||
- Системи за памет и умения---## Code Style
|
||||
|
||||
- **ESLint** — Run `npm run lint` before committing
|
||||
- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
|
||||
- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
|
||||
- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
|
||||
- **Zod validation** — Use Zod v4 schemas for all API input validation
|
||||
- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
-**ESLint**— Стартирайте `npm run lint` преди извършване -**Prettier**— Автоматично форматирано чрез `lint-staged` при ангажиране (2 интервала, точка и запетая, двойни кавички, ширина 100 знака, es5 запетая в края) -**TypeScript**— Всички `src/` кодове се използват `.ts`/`.tsx`; `open-sse/` използва `.ts`/`.js`; документ с TSDoc (`@param`, `@returns`, `@throws`) -**Без `eval()`**— ESLint налага `no-eval`, `no-implied-eval`, `no-new-func` -**Zod валидиране**— Използвайте Zod v4 схеми за всички входни валидации на API -**Именуване**: Файлове = camelCase/kebab-case, компоненти = PascalCase, константи = UPPER_SNAKE---## Project Structure
|
||||
|
||||
```
|
||||
src/ # TypeScript (.ts / .tsx)
|
||||
@@ -244,56 +216,31 @@ docs/ # Documentation
|
||||
|
||||
### Step 1: Register Provider Constants
|
||||
|
||||
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
|
||||
Добавете към `src/shared/constants/providers.ts` — Zod-валидирано при зареждане на модула.### Стъпка 2: Добавяне на изпълнител (ако е необходима персонализирана логика)
|
||||
|
||||
### Step 2: Add Executor (if custom logic needed)
|
||||
Създайте изпълнител в `open-sse/executors/your-provider.ts`, като разширите базовия изпълнител.### Стъпка 3: Добавете преводач (ако форматът не е OpenAI)
|
||||
|
||||
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
|
||||
Създайте преводачи на заявка/отговор в `open-sse/translator/`.### Стъпка 4: Добавете OAuth Config (ако е базиран на OAuth)
|
||||
|
||||
### Step 3: Add Translator (if non-OpenAI format)
|
||||
Добавете идентификационни данни за OAuth в `src/lib/oauth/constants/oauth.ts` и услуга в `src/lib/oauth/services/`.### Стъпка 5: Регистрирайте модели
|
||||
|
||||
Create request/response translators in `open-sse/translator/`.
|
||||
Добавете дефиниции на модели в `open-sse/config/providerRegistry.ts`.### Стъпка 6: Добавете тестове
|
||||
|
||||
### Step 4: Add OAuth Config (if OAuth-based)
|
||||
Напишете модулни тестове в `tests/unit/`, покривайки минимум:
|
||||
|
||||
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
|
||||
- Регистрация при доставчик
|
||||
- Превод на заявка/отговор
|
||||
- Обработка на грешки---## Pull Request Checklist
|
||||
|
||||
### Step 5: Register Models
|
||||
- [ ] Тестовете преминават („npm тест“)
|
||||
- [ ] Linting преминава (`npm run lint`)
|
||||
- [ ] Компилацията е успешна (`npm run build`)
|
||||
- [] TypeScript типове, добавени за нови публични функции и интерфейси
|
||||
- [ ] Няма твърдо кодирани тайни или резервни стойности
|
||||
- [ ] Всички входове, валидирани със схеми на Zod
|
||||
- [ ] CHANGELOG актуализиран (ако промяната е пред потребителя)
|
||||
- [ ] Актуализирана документация (ако е приложимо)---## Releasing
|
||||
|
||||
Add model definitions in `open-sse/config/providerRegistry.ts`.
|
||||
Изданията се управляват чрез работен процес `/generate-release`. Когато се създаде ново издание на GitHub, пакетът се**автоматично публикува в npm**чрез GitHub Actions.---## Getting Help
|
||||
|
||||
### Step 6: Add Tests
|
||||
|
||||
Write unit tests in `tests/unit/` covering at minimum:
|
||||
|
||||
- Provider registration
|
||||
- Request/response translation
|
||||
- Error handling
|
||||
|
||||
---
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- [ ] Tests pass (`npm test`)
|
||||
- [ ] Linting passes (`npm run lint`)
|
||||
- [ ] Build succeeds (`npm run build`)
|
||||
- [ ] TypeScript types added for new public functions and interfaces
|
||||
- [ ] No hardcoded secrets or fallback values
|
||||
- [ ] All inputs validated with Zod schemas
|
||||
- [ ] CHANGELOG updated (if user-facing change)
|
||||
- [ ] Documentation updated (if applicable)
|
||||
|
||||
---
|
||||
|
||||
## Releasing
|
||||
|
||||
Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
|
||||
|
||||
---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
||||
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **ADRs**: See `docs/adr/` for architectural decision records
|
||||
-**Архитектура**: Вижте [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**API справка**: Вижте [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**Проблеми**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**ADRs**: Вижте `docs/adr/` за записи на архитектурни решения
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,179 +1,150 @@
|
||||
# Security Policy (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [hi](../hi/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md) · 🇹🇷 [tr](../tr/SECURITY.md)
|
||||
|
||||
---
|
||||
|
||||
## Reporting Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability in OmniRoute, please report it responsibly:
|
||||
Ако откриете уязвимост на сигурността в OmniRoute, моля, докладвайте отговорно:
|
||||
|
||||
1. **DO NOT** open a public GitHub issue
|
||||
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
|
||||
3. Include: description, reproduction steps, and potential impact
|
||||
1.**НЕ**отваряйте публичен проблем на GitHub 2. Използвайте [Съвети за сигурност на GitHub](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. Включете: описание, стъпки за възпроизвеждане и потенциално действие## Response Timeline
|
||||
|
||||
## Response Timeline
|
||||
| Етап | Цел |
|
||||
| -------------------- | ------------------------- | -------------------- |
|
||||
| Признание | 48 часа |
|
||||
| Сортиране и оценка | 5 работни дни |
|
||||
| Издаване на корекция | 14 работни дни (критично) | ## Поддържани версии |
|
||||
|
||||
| Stage | Target |
|
||||
| ------------------- | --------------------------- |
|
||||
| Acknowledgment | 48 hours |
|
||||
| Triage & Assessment | 5 business days |
|
||||
| Patch Release | 14 business days (critical) |
|
||||
| Версия | Състояние на поддръжка |
|
||||
| ------- | ---------------------- | --------------------------- |
|
||||
| 3.4.x | ✅ Активен |
|
||||
| 3.0.x | ✅ Сигурност |
|
||||
| < 3.0.0 | ❌ Не се поддържа | ---## Security Architecture |
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Support Status |
|
||||
| ------- | -------------- |
|
||||
| 3.4.x | ✅ Active |
|
||||
| 3.0.x | ✅ Security |
|
||||
| < 3.0.0 | ❌ Unsupported |
|
||||
|
||||
---
|
||||
|
||||
## Security Architecture
|
||||
|
||||
OmniRoute implements a multi-layered security model:
|
||||
|
||||
```
|
||||
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
|
||||
```
|
||||
OmniRoute прилага многослоен модел за сигурност:`
|
||||
Заявка → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider`
|
||||
|
||||
### 🔐 Authentication & Authorization
|
||||
|
||||
| Feature | Implementation |
|
||||
| -------------------- | ---------------------------------------------------------- |
|
||||
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
|
||||
| **API Key Auth** | HMAC-signed keys with CRC validation |
|
||||
| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
|
||||
| **Token Refresh** | Automatic OAuth token refresh before expiry |
|
||||
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
|
||||
| **MCP Scopes** | 10 granular scopes for MCP tool access control |
|
||||
| Характеристика | Изпълнение |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------- | ------------------------- |
|
||||
| **Влизане в таблото за управление** | Базирано на парола удостоверяване с JWT токени (HttpOnly бисквитки) |
|
||||
| **API Key Auth** | HMAC-подписани ключове с CRC валидиране |
|
||||
| **OAuth 2.0 + PKCE** | Сигурно удостоверяване на доставчик (Claude, Codex, Gemini, Cursor и др.) |
|
||||
| **Token Refresh** | Автоматично опресняване на OAuth токена преди изтичане |
|
||||
| **Защитени бисквитки** | `AUTH_COOKIE_SECURE=true` за HTTPS среди |
|
||||
| **MCP обхвати** | 10 подробни обхвата за контрол на достъпа до MCP инструмент | ### 🛡️ Encryption at Rest |
|
||||
|
||||
### 🛡️ Encryption at Rest
|
||||
Всички чувствителни данни, съхранявани в SQLite, са криптирани с помощта на**AES-256-GCM**с деривация на scrypt ключ:
|
||||
|
||||
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
|
||||
- API ключове, токени за достъп, токени за опресняване и токени за идентификация
|
||||
- Версионен формат: `enc:v1:<iv>:<ciphertext>:<authTag>`
|
||||
- Режим на преминаване (обикновен текст), когато `STORAGE_ENCRYPTION_KEY` не е зададен```bash
|
||||
|
||||
- API keys, access tokens, refresh tokens, and ID tokens
|
||||
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
|
||||
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
|
||||
|
||||
```bash
|
||||
# Generate encryption key:
|
||||
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### 🧠 Prompt Injection Guard
|
||||
|
||||
Middleware that detects and blocks prompt injection attacks in LLM requests:
|
||||
Мидулуер, който открива и блокира атаки за бързо инжектиране в LLM заявки:
|
||||
|
||||
| Pattern Type | Severity | Example |
|
||||
| Тип модел | Тежест | Пример |
|
||||
| ------------------- | -------- | ---------------------------------------------- |
|
||||
| System Override | High | "ignore all previous instructions" |
|
||||
| Role Hijack | High | "you are now DAN, you can do anything" |
|
||||
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
|
||||
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
|
||||
| Instruction Leak | Medium | "show me your system prompt" |
|
||||
| Отмяна на системата | Високо | "игнорирайте всички предишни инструкции" |
|
||||
| Отвличане на роли | Високо | "вече си ДАН, можеш да правиш всичко" |
|
||||
| Инжектиране на разделител | Средно | Кодирани разделители за прекъсване на контекстните граници |
|
||||
| ДАН/Джейлбрейк | Високо | Известни шаблони за подкана за бягство от затвора |
|
||||
| Изтичане на инструкции | Средно | "покажи ми системния ред" |
|
||||
|
||||
Configure via dashboard (Settings → Security) or `.env`:
|
||||
|
||||
```env
|
||||
INPUT_SANITIZER_ENABLED=true
|
||||
INPUT_SANITIZER_MODE=block # warn | block | redact
|
||||
```
|
||||
Конфигурирайте чрез табло за управление (Настройки → Сигурност) или `.env`:```env
|
||||
INPUT_SANITIZER_ENABLED=вярно
|
||||
INPUT_SANITIZER_MODE=блок # предупреждение | блокирам | редактирам```
|
||||
|
||||
### 🔒 PII Redaction
|
||||
|
||||
Automatic detection and optional redaction of personally identifiable information:
|
||||
Автоматично откриване и опционално редактиране на лична информация:
|
||||
|
||||
| PII Type | Pattern | Replacement |
|
||||
| Тип PII | Модел | Замяна |
|
||||
| ------------- | --------------------- | ------------------ |
|
||||
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
|
||||
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
|
||||
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
|
||||
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
|
||||
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
|
||||
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
|
||||
|
||||
```env
|
||||
| Имейл | `user@domain.com` | „[EMAIL_REDACTED]“ |
|
||||
| CPF (Бразилия) | `123.456.789-00` | „[CPF_REDACTED]“ |
|
||||
| CNPJ (Бразилия) | `12.345.678/0001-00` | „[CNPJ_REDACTED]“ |
|
||||
| Кредитна карта | „4111-1111-1111-1111“ | „[CC_REDACTED]“ |
|
||||
| Телефон | `+55 11 99999-9999` | „[PHONE_REDACTED]“ |
|
||||
| SSN (САЩ) | `123-45-6789` | „[SSN_REDACTED]“ |```env
|
||||
PII_REDACTION_ENABLED=true
|
||||
```
|
||||
````
|
||||
|
||||
### 🌐 Network Security
|
||||
|
||||
| Feature | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------- |
|
||||
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
|
||||
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
|
||||
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
|
||||
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
|
||||
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
|
||||
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
|
||||
| Характеристика | Описание |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------ |
|
||||
| **CORS** | Конфигурираме начален контрол (`CORS_ORIGIN` env var, по подразбиране `*`) |
|
||||
| **IP филтриране** | Списък с разрешени/блокирани IP диапазони в таблото |
|
||||
| **Ограничаване на скоростта** | Ограничения на скоростта за всеки доставчик с автоматично заплащане |
|
||||
| **Anti-Thundering Herd** | Mutex + затваряне на връзката предотвратява каскадно 502s |
|
||||
| **TLS пръстов отпечатък** | Подобно на браузъра TLS фалшифициране на пръстови отпечатъци за намаляване на откриването на бот |
|
||||
| **CLI пръстов отпечатък** | Подреждане на заглавка/тяло на доставчика, за да съответства на собствените CLI подписи | ### 🔌 Устойчивост и наличност |
|
||||
|
||||
### 🔌 Resilience & Availability
|
||||
| Характеристика | Описание |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------- | ----------------- |
|
||||
| **Прекъсвач** | 3 състояния (Затворено → Отворено → Полуотворено) на доставчика, поддържано от SQLite |
|
||||
| **Искане на идемпотентност** | 5-секунден прозорец за дедупиране за дублирани заявки |
|
||||
| **Експоненциално отстъпление** | Автоматичен повторен опит с нарастващи закъснения |
|
||||
| **Здравно табло** | Мониторинг на здравето на доставчика в реално време | ### 📋 Compliance |
|
||||
|
||||
| Feature | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------ |
|
||||
| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
|
||||
| **Request Idempotency** | 5-second dedup window for duplicate requests |
|
||||
| **Exponential Backoff** | Automatic retry with increasing delays |
|
||||
| **Health Dashboard** | Real-time provider health monitoring |
|
||||
| Характеристика | Описание |
|
||||
| --------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------ |
|
||||
| **Запазване на регистрационни файлове** | Автоматично след почистване `CALL_LOG_RETENTION_DAYS` |
|
||||
| **Отказ без влизане** | Флагът `noLog` за API ключ деактивира регистрацията на заявки |
|
||||
| **Дневник за проверка** | Административни действия, последвани в таблицата `audit_log` |
|
||||
| **MCP Одит** | Поддържано от SQLite обикновено регистриране за всички извиквания на MCP инструмент |
|
||||
| **Проверка на Zod** | Всички API входове, валидирани със схеми на Zod v4 при зареждане на модул | ---## Required Environment Variables |
|
||||
|
||||
### 📋 Compliance
|
||||
Всички тайни трябва да бъдат лоши преди стартиране на сървъра. Сървърът ще**откаже бързо**, ако те липсва или са слаби.```bash
|
||||
|
||||
| Feature | Description |
|
||||
| ------------------ | ----------------------------------------------------------- |
|
||||
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
|
||||
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
|
||||
| **Audit Log** | Administrative actions tracked in `audit_log` table |
|
||||
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
|
||||
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
|
||||
# ЗАДЪЛЖИТЕЛНО — сървърът няма да стартира без тези:
|
||||
|
||||
---
|
||||
JWT_SECRET=$(openssl rand -base64 48) # мин. 32 знака
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # мин. 16 знака
|
||||
|
||||
## Required Environment Variables
|
||||
# ПРЕПОРЪЧИТЕЛНО — разрешава криптиране в покой:
|
||||
|
||||
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)```
|
||||
|
||||
```bash
|
||||
# REQUIRED — server will not start without these:
|
||||
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
|
||||
|
||||
# RECOMMENDED — enables encryption at rest:
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
|
||||
|
||||
---
|
||||
Сървърът активно отхвърля известни слаби стойности като `changeme`, `secret` или `password`.---
|
||||
|
||||
## Docker Security
|
||||
|
||||
- Use non-root user in production
|
||||
- Mount secrets as read-only volumes
|
||||
- Never copy `.env` files into Docker images
|
||||
- Use `.dockerignore` to exclude sensitive files
|
||||
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
|
||||
|
||||
```bash
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--read-only \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
-e JWT_SECRET="$(openssl rand -base64 48)" \
|
||||
- Използвайте не-root потребител в производството
|
||||
- Монтиране на тайни като томове само за четене
|
||||
- Никога не копирайте `.env` файлове в Docker изображения
|
||||
- Използвайте `.dockerignore`, за да изключите чувствителни файлове
|
||||
- Задайте `AUTH_COOKIE_SECURE=true`, когато сте зад HTTPS```bash
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--read-only \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
-e JWT_SECRET="$(openssl rand -base64 48)" \
|
||||
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
|
||||
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
|
||||
diegosouzapw/omniroute:latest
|
||||
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
|
||||
diegosouzapw/omniroute:latest
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Run `npm audit` regularly
|
||||
- Keep dependencies updated
|
||||
- The project uses `husky` + `lint-staged` for pre-commit checks
|
||||
- CI pipeline runs ESLint security rules on every push
|
||||
- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)
|
||||
- Редовно изпълнете `npm audit`
|
||||
- Поддържайте зависимостите от актуализациите
|
||||
- Проектът използва `husky` + `lint-staged` за проверки преди ангажиране
|
||||
- CI тръбопроводът изпълнява правила за сигурност ESLint при всяко натискане
|
||||
- Константа на доставчика, валидирана при зареждане на модул чрез Zod (`src/shared/validation/providerSchema.ts`)
|
||||
```
|
||||
|
||||
@@ -1,40 +1,26 @@
|
||||
# OmniRoute A2A Server Documentation (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [hi](../../hi/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md) · 🇹🇷 [tr](../../tr/docs/A2A-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute като интелигентен агент за маршрутизиране## Agent Discovery```bash
|
||||
> curl http://localhost:20128/.well-known/agent.json
|
||||
|
||||
## Agent Discovery
|
||||
````
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
Връща картата на агента, описваща възможностите, уменията и изискванията за удостоверяване в OmniRoute.---## Authentication
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
Всички заявки `/a2a` изискват API ключ чрез заглавката `Authorization`:```
|
||||
Упълномощаване: Носител YOUR_OMNIROUTE_API_KEY```
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
|
||||
---
|
||||
Ако на сървъра не е конфигуриран API ключ, удостоверяването се заобикаля.---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
Изпраща съобщение до умение и изчаква пълния отговор.```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
@@ -48,153 +34,137 @@ curl -X POST http://localhost:20128/a2a \
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**Отговор:**`json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"result": {
|
||||
"резултат": {
|
||||
"task": { "id": "uuid", "state": "completed" },
|
||||
"artifacts": [{ "type": "text", "content": "..." }],
|
||||
"metadata": {
|
||||
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
|
||||
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
|
||||
"артефакти": [{ "тип": "текст", "съдържание": "..." }],
|
||||
"метаданни": {
|
||||
"routing_explanation": "Избран клод-сонет чрез доставчик \"anthropic\" (закъснение: 1200ms, цена: $0,003)",
|
||||
"cost_envelope": { "estimated": 0,005, "actual": 0,003, "currency": "USD" },
|
||||
"resilience_trace": [
|
||||
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
|
||||
],
|
||||
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
|
||||
"policy_verdict": { "allowed": true, "reason": "в рамките на бюджета и квотите" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
}`
|
||||
|
||||
### `message/stream` — SSE Streaming
|
||||
|
||||
Same as `message/send` but returns Server-Sent Events for real-time streaming.
|
||||
|
||||
```bash
|
||||
Същото като `message/send`, но връща изпратени от сървъра събития за поточно предаване в реално време.```bash
|
||||
curl -N -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
|
||||
**SSE Events:**
|
||||
````
|
||||
|
||||
```
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
|
||||
**SSE събития:**```
|
||||
данни: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
: сърдечен ритъм 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
|
||||
```
|
||||
данни: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}```
|
||||
|
||||
### `tasks/get` — Query Task Status
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
-H "Тип съдържание: приложение/json" \
|
||||
-H "Упълномощаване: Носител YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'```
|
||||
|
||||
### `tasks/cancel` — Cancel a Task
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"3","method":"tasks/cancel","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
-H "Тип съдържание: приложение/json" \
|
||||
-H "Упълномощаване: Носител YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"3","method":"tasks/cancel","params":{"taskId":"TASK_UUID"}}'```
|
||||
|
||||
---
|
||||
|
||||
## Available Skills
|
||||
|
||||
| Skill | Description |
|
||||
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. |
|
||||
| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. |
|
||||
|
||||
---
|
||||
| Умение | Описание |
|
||||
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `интелигентно маршрутизиране` | Подкани за маршрути чрез интелигентния тръбопровод на OmniRoute. Връща отговор с обяснение на маршрута, цена и проследяване на устойчивостта. |
|
||||
| `управление на квоти` | Отговаря на запитвания на естествен език относно квотите на доставчика, предлага безплатни комбинации и предоставя класиране на квотите. |---
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
````
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
изпратен → работи → завършен
|
||||
→ неуспешно
|
||||
→ отменен```
|
||||
|
||||
---
|
||||
- Задачите изтичат след 5 минути (може да се конфигурира)
|
||||
- Състояния на терминала: `завършено`, `неуспешно`, `отменено`
|
||||
- Дневникът на събитията проследява всеки преход на състояние---
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Meaning |
|
||||
| :----- | :----------------------------- |
|
||||
| -32700 | Parse error (invalid JSON) |
|
||||
| -32600 | Invalid request / Unauthorized |
|
||||
| -32601 | Method or skill not found |
|
||||
| -32602 | Invalid params |
|
||||
| -32603 | Internal error |
|
||||
|
||||
---
|
||||
| Код | Значение |
|
||||
| :----- | :---------------------------------- | --- |
|
||||
| -32700 | Грешка при анализа (невалиден JSON) |
|
||||
| -32600 | Невалидна заявка / Неоторизирана |
|
||||
| -32601 | Методът или умението не са намерени |
|
||||
| -32602 | Невалидни параметри |
|
||||
| -32603 | Вътрешна грешка | --- |
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
````python
|
||||
заявки за импортиране
|
||||
|
||||
resp = requests.post("http://localhost:20128/a2a", json={
|
||||
"jsonrpc": "2.0", "id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"метод": "съобщение/изпращане",
|
||||
"параметри": {
|
||||
"умение": "интелигентно маршрутизиране",
|
||||
"messages": [{"role": "user", "content": "Hello"}]
|
||||
}
|
||||
}, headers={"Authorization": "Bearer YOUR_KEY"})
|
||||
}, headers={"Упълномощаване": "Носител YOUR_KEY"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
print(result["metadata"]["routing_explanation"])
|
||||
```
|
||||
резултат = resp.json()["резултат"]
|
||||
печат (резултат["артефакти"][0]["съдържание"])
|
||||
print(result["metadata"]["routing_explanation"])```
|
||||
|
||||
### TypeScript (fetch)
|
||||
|
||||
```typescript
|
||||
const resp = await fetch("http://localhost:20128/a2a", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer YOUR_KEY",
|
||||
метод: "POST",
|
||||
заглавки: {
|
||||
"Content-Type": "приложение/json",
|
||||
Упълномощаване: "Носител YOUR_KEY",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
тяло: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "1",
|
||||
method: "message/send",
|
||||
params: {
|
||||
skill: "smart-routing",
|
||||
messages: [{ role: "user", content: "Hello" }],
|
||||
метод: "съобщение/изпрати",
|
||||
параметри: {
|
||||
умение: "интелигентно маршрутизиране",
|
||||
съобщения: [{ роля: "потребител", съдържание: "Здравей" }],
|
||||
},
|
||||
}),
|
||||
});
|
||||
const { result } = await resp.json();
|
||||
console.log(result.metadata.routing_explanation);
|
||||
```
|
||||
const {резултат} = изчакайте resp.json();
|
||||
console.log(result.metadata.routing_explanation);```
|
||||
````
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
# API Reference (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [hi](../../hi/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md) · 🇹🇷 [tr](../../tr/docs/API_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
---
|
||||
Пълна справка за всички крайни точки на OmniRoute API.---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
- [Завършвания на чат](#chat-completions)
|
||||
- [Вграждания](#вграждания)
|
||||
- [Генериране на изображение](#image-generation)
|
||||
- [Списък с модели](#list-models)
|
||||
- [Крайни точки за съвместимост](#compatibility-endpoints)
|
||||
- [Семантичен кеш](#semantic-cache)
|
||||
- [Табло за управление и управление](#табло за управление--управление)
|
||||
- [Обработка на заявка](#request-processing)
|
||||
- [Удостоверяване](#удостоверяване)---
|
||||
|
||||
## Chat Completions
|
||||
|
||||
@@ -40,22 +36,20 @@ Content-Type: application/json
|
||||
|
||||
### Custom Headers
|
||||
|
||||
| Header | Direction | Description |
|
||||
| ------------------------ | --------- | ------------------------------------------------ |
|
||||
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
|
||||
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
|
||||
| `X-Session-Id` | Request | Sticky session key for external session affinity |
|
||||
| `x_session_id` | Request | Underscore variant also accepted (direct HTTP) |
|
||||
| `Idempotency-Key` | Request | Dedup key (5s window) |
|
||||
| `X-Request-Id` | Request | Alternative dedup key |
|
||||
| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) |
|
||||
| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated |
|
||||
| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on |
|
||||
| `X-OmniRoute-Session-Id` | Response | Effective session ID used by OmniRoute |
|
||||
| Заглавка | Посока | Описание |
|
||||
| ------------------------ | ------- | -------------------------------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | Заявка | Задайте `true`, за да заобиколите кеша |
|
||||
| `X-OmniRoute-Progress` | Заявка | Задайте на `true` за прогрес събития |
|
||||
| `X-Session-Id` | Заявка | Залепващ сесиен ключ за афинитет към външна сесия |
|
||||
| `x_session_id` | Заявка | Вариантът с долна черта също се приема (директен HTTP) |
|
||||
| `Idempotency-Key` | Заявка | Ключ за дедупиране (5s прозорец) |
|
||||
| `X-Request-Id` | Заявка | Алтернативен дедуп ключ |
|
||||
| `X-OmniRoute-Cache` | Отговор | `HIT` или `MISS` (без стрийминг) |
|
||||
| `X-OmniRoute-Idempotent` | Отговор | `true` ако е дедупликиран |
|
||||
| `X-OmniRoute-Progress` | Отговор | `enabled`, ако проследяването на напредъка е на |
|
||||
| `X-OmniRoute-Session-Id` | Отговор | Идентификатор на ефективна сесия, използван от OmniRoute |
|
||||
|
||||
> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
|
||||
|
||||
---
|
||||
> Забележка на Nginx: ако разчитате на заглавки с долна черта (например `x_session_id`), активирайте `underscores_in_headers on;`.---
|
||||
|
||||
## Embeddings
|
||||
|
||||
@@ -70,12 +64,13 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
Налични доставчици: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.```bash
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -91,14 +86,15 @@ Content-Type: application/json
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
Налични доставчици: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.```bash
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -109,26 +105,24 @@ GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Compatibility Endpoints
|
||||
|
||||
| Method | Path | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Anthropic |
|
||||
| POST | `/v1/responses` | OpenAI Responses |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| GET | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Anthropic |
|
||||
| GET | `/v1beta/models` | Gemini |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
|
||||
### Dedicated Provider Routes
|
||||
| Метод | Път | Формат |
|
||||
| ---------- | --------------------------- | -------------------------- | ----------------------------- |
|
||||
| ПУБЛИКАЦИЯ | `/v1/chat/completions` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/съобщения` | Антропен |
|
||||
| ПУБЛИКАЦИЯ | `/v1/отговори` | OpenAI отговори |
|
||||
| ПУБЛИКАЦИЯ | `/v1/вграждания` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/images/generations` | OpenAI |
|
||||
| ВЗЕМЕТЕ | `/v1/модели` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/messages/count_tokens` | Антропен |
|
||||
| ВЗЕМЕТЕ | `/v1beta/models` | Близнаци |
|
||||
| ПУБЛИКАЦИЯ | `/v1beta/models/{...path}` | Gemini генерира съдържание |
|
||||
| ПУБЛИКАЦИЯ | `/v1/api/чат` | Олама | ### Dedicated Provider Routes |
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
@@ -136,9 +130,7 @@ POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
---
|
||||
Префиксът на доставчика се добавя автоматично, ако липсва. Несъответстващите модели връщат „400“.---
|
||||
|
||||
## Semantic Cache
|
||||
|
||||
@@ -150,22 +142,21 @@ GET /api/cache/stats
|
||||
DELETE /api/cache/stats
|
||||
```
|
||||
|
||||
Response example:
|
||||
|
||||
```json
|
||||
Пример за отговор:```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
```
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -173,165 +164,129 @@ Response example:
|
||||
|
||||
### Authentication
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------------- | ------- | --------------------- |
|
||||
| `/api/auth/login` | POST | Login |
|
||||
| `/api/auth/logout` | POST | Logout |
|
||||
| `/api/settings/require-login` | GET/PUT | Toggle login required |
|
||||
| `/api/auth/login` | ПУБЛИКАЦИЯ | Вход |
|
||||
| `/api/auth/logout` | ПУБЛИКАЦИЯ | Изход |
|
||||
| `/api/settings/require-login` | ВЗЕМИ/ПОСТАВИ | Изисква се превключване на влизане |### Provider Management
|
||||
|
||||
### Provider Management
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | --------------- | ------------------------ |
|
||||
| `/api/providers` | GET/POST | List / create providers |
|
||||
| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider |
|
||||
| `/api/providers/[id]/test` | POST | Test provider connection |
|
||||
| `/api/providers/[id]/models` | GET | List provider models |
|
||||
| `/api/providers/validate` | POST | Validate provider config |
|
||||
| `/api/provider-nodes*` | Various | Provider node management |
|
||||
| `/api/provider-models` | GET/POST/DELETE | Custom models |
|
||||
| `/api/провайдери` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Списък / създаване на доставчици |
|
||||
| `/api/провайдери/[id]` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Управление на доставчик |
|
||||
| `/api/providers/[id]/test` | ПУБЛИКАЦИЯ | Тествайте връзката с доставчик |
|
||||
| `/api/providers/[id]/models` | ВЗЕМЕТЕ | Избройте модели на доставчици |
|
||||
| `/api/providers/validate` | ПУБЛИКАЦИЯ | Проверка на конфигурацията на доставчика |
|
||||
| `/api/провайдер-възли*` | Различни | Управление на възел на доставчик |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Персонализирани модели |### OAuth Flows
|
||||
|
||||
### OAuth Flows
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------------- | ------- | ----------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
|
||||
| `/api/oauth/[доставчик]/[действие]` | Различни | Специфичен за доставчика OAuth |### Routing & Config
|
||||
|
||||
### Routing & Config
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------- | -------- | ----------------------------- |
|
||||
| `/api/models/alias` | GET/POST | Model aliases |
|
||||
| `/api/models/catalog` | GET | All models by provider + type |
|
||||
| `/api/combos*` | Various | Combo management |
|
||||
| `/api/keys*` | Various | API key management |
|
||||
| `/api/pricing` | GET | Model pricing |
|
||||
| `/api/models/alias` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Псевдоними на модели |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Всички модели по доставчик + тип |
|
||||
| `/api/combos*` | Различни | Комбо управление |
|
||||
| `/api/ключове*` | Различни | Управление на API ключове |
|
||||
| `/api/pricing` | ВЗЕМЕТЕ | Моделна цена |### Usage & Analytics
|
||||
|
||||
### Usage & Analytics
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | ------ | -------------------- |
|
||||
| `/api/usage/history` | ВЗЕМЕТЕ | История на използването |
|
||||
| `/api/usage/logs` | ВЗЕМЕТЕ | Дневници за използване |
|
||||
| `/api/usage/request-logs` | ВЗЕМЕТЕ | Дневници на ниво заявка |
|
||||
| `/api/usage/[connectionId]` | ВЗЕМЕТЕ | Използване на връзка |### Settings
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | -------------------- |
|
||||
| `/api/usage/history` | GET | Usage history |
|
||||
| `/api/usage/logs` | GET | Usage logs |
|
||||
| `/api/usage/request-logs` | GET | Request-level logs |
|
||||
| `/api/usage/[connectionId]` | GET | Per-connection usage |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------------ | ------------- | ---------------------- |
|
||||
| `/api/настройки` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/КРЕПКА | Общи настройки |
|
||||
| `/api/настройки/прокси` | ВЗЕМИ/ПОСТАВИ | Конфигурация на мрежов прокси |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Тествайте прокси връзката |
|
||||
| `/api/настройки/ip-филтър` | ВЗЕМИ/ПОСТАВИ | Списък с разрешени/блокирани IP адреси |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Бюджет на жетон за разсъждение |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Глобална системна подкана |### Monitoring
|
||||
|
||||
### Settings
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------ | ---------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| `/api/сесии` | ВЗЕМЕТЕ | Проследяване на активна сесия |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Лимити за лихви по сметка |
|
||||
| `/api/мониторинг/здраве` | ВЗЕМЕТЕ | Проверка на състоянието + резюме на доставчика (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
|
||||
| `/api/cache/stats` | ПОЛУЧАВАНЕ/ИЗТРИВАНЕ | Кеш статистики / изчистване |### Backup & Export/Import
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------------- | ------------- | ---------------------- |
|
||||
| `/api/settings` | GET/PUT/PATCH | General settings |
|
||||
| `/api/settings/proxy` | GET/PUT | Network proxy config |
|
||||
| `/api/settings/proxy/test` | POST | Test proxy connection |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | ------ | ----------------------------------------------- |
|
||||
| `/api/db-backups` | ВЗЕМЕТЕ | Избройте наличните резервни копия |
|
||||
| `/api/db-backups` | ПОСТАВЕТЕ | Създайте ръчно архивиране |
|
||||
| `/api/db-backups` | ПУБЛИКАЦИЯ | Възстановяване от конкретен архив |
|
||||
| `/api/db-backups/export` | ВЗЕМЕТЕ | Изтегляне на база данни като .sqlite файл |
|
||||
| `/api/db-backups/import` | ПУБЛИКАЦИЯ | Качете .sqlite файл, за да замените базата данни |
|
||||
| `/api/db-backups/exportAll` | ВЗЕМЕТЕ | Изтеглете пълното архивиране като .tar.gz архив |### Cloud Sync
|
||||
|
||||
### Monitoring
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `/api/sessions` | GET | Active session tracking |
|
||||
| `/api/rate-limits` | GET | Per-account rate limits |
|
||||
| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
|
||||
| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
|
||||
|
||||
### Backup & Export/Import
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | --------------------------------------- |
|
||||
| `/api/db-backups` | GET | List available backups |
|
||||
| `/api/db-backups` | PUT | Create a manual backup |
|
||||
| `/api/db-backups` | POST | Restore from a specific backup |
|
||||
| `/api/db-backups/export` | GET | Download database as .sqlite file |
|
||||
| `/api/db-backups/import` | POST | Upload .sqlite file to replace database |
|
||||
| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive |
|
||||
|
||||
### Cloud Sync
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------- | ------- | --------------------- |
|
||||
| `/api/sync/cloud` | Various | Cloud sync operations |
|
||||
| `/api/sync/initialize` | POST | Initialize sync |
|
||||
| `/api/cloud/*` | Various | Cloud management |
|
||||
| `/api/sync/cloud` | Различни | Операции за синхронизиране в облак |
|
||||
| `/api/sync/initialize` | ПУБЛИКАЦИЯ | Инициализиране на синхронизиране |
|
||||
| `/api/cloud/*` | Различни | Облачно управление |### Tunnels
|
||||
|
||||
### Tunnels
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------- | ------ | --------------------------------------------------------------------- |
|
||||
| `/api/tunnels/cloudflared` | ВЗЕМЕТЕ | Прочетете състоянието на инсталиране/изпълнение на Cloudflare Quick Tunnel за таблото за управление |
|
||||
| `/api/tunnels/cloudflared` | ПУБЛИКАЦИЯ | Активиране или деактивиране на Cloudflare Quick Tunnel (`action=enable/disable`) |### CLI Tools
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | ----------------------------------------------------------------------- |
|
||||
| `/api/tunnels/cloudflared` | GET | Read Cloudflare Quick Tunnel install/runtime status for the dashboard |
|
||||
| `/api/tunnels/cloudflared` | POST | Enable or disable the Cloudflare Quick Tunnel (`action=enable/disable`) |
|
||||
|
||||
### CLI Tools
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------------- | ------ | ------------------- |
|
||||
| `/api/cli-tools/claude-settings` | GET | Claude CLI status |
|
||||
| `/api/cli-tools/codex-settings` | GET | Codex CLI status |
|
||||
| `/api/cli-tools/droid-settings` | GET | Droid CLI status |
|
||||
| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status |
|
||||
| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime |
|
||||
| `/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 responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
CLI отговорите включват: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.### ACP Agents
|
||||
|
||||
### ACP Agents
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------- | ------ | -------------------------------------------------------- |
|
||||
| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status |
|
||||
| `/api/acp/agents` | POST | Add custom agent or refresh detection cache |
|
||||
| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param |
|
||||
| `/api/acp/agents` | ВЗЕМЕТЕ | Избройте всички открити агенти (вградени + персонализирани) със статус |
|
||||
| `/api/acp/agents` | ПУБЛИКАЦИЯ | Добавете персонализиран агент или опреснете кеша за откриване |
|
||||
| `/api/acp/agents` | ИЗТРИВАНЕ | Премахнете персонализиран агент чрез параметър на заявка `id` |
|
||||
|
||||
GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
|
||||
GET отговорът включва „агенти []“ (идентификатор, име, двоичен файл, версия, инсталиран, протокол, е Персонализиран) и „обобщение“ (общо, инсталирано, неНамерено, вградено, персонализирано).### Resilience & Rate Limits
|
||||
|
||||
### Resilience & Rate Limits
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------- | --------- | ------------------------------ |
|
||||
| `/api/устойчивост` | ВЗЕМЕТЕ/КРЕПКА | Вземете/актуализирайте профили за устойчивост |
|
||||
| `/api/resilience/reset` | ПУБЛИКАЦИЯ | Нулиране на прекъсвачи |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка |
|
||||
| `/api/лимит на скоростта` | ВЗЕМЕТЕ | Конфигурация на глобален лимит на скоростта |### Evals
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------- | --------- | ------------------------------- |
|
||||
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
|
||||
| `/api/resilience/reset` | POST | Reset circuit breakers |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
| `/api/rate-limit` | GET | Global rate limit configuration |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------ | -------- | ---------------------------------- |
|
||||
| `/api/evals` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Избройте eval пакети / изпълнете оценка |### Policies
|
||||
|
||||
### Evals
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------ | -------- | --------------------------------- |
|
||||
| `/api/evals` | GET/POST | List eval suites / run evaluation |
|
||||
|
||||
### Policies
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
|
||||
| `/api/policies` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Управление на правилата за маршрутизиране |### Compliance
|
||||
|
||||
### Compliance
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | ВЗЕМЕТЕ | Дневник за проверка на съответствието (последно N) |### v1beta (Gemini-Compatible)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------- | ------ | ---------------------------------- |
|
||||
| `/v1beta/models` | ВЗЕМЕТЕ | Избройте модели във формат Gemini |
|
||||
| `/v1beta/models/{...path}` | ПУБЛИКАЦИЯ | Крайна точка на Gemini `generateContent` |
|
||||
|
||||
### v1beta (Gemini-Compatible)
|
||||
Тези крайни точки отразяват API формата на Gemini за клиенти, които очакват естествена съвместимост с Gemini SDK.### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | --------------------------------- |
|
||||
| `/v1beta/models` | GET | List models in Gemini format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
|
||||
|
||||
These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
|
||||
|
||||
### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------- | ------ | ---------------------------------------------------- |
|
||||
| `/api/init` | GET | Application initialization check (used on first run) |
|
||||
| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) |
|
||||
| `/api/restart` | POST | Trigger graceful server restart |
|
||||
| `/api/shutdown` | POST | Trigger graceful server shutdown |
|
||||
| `/api/init` | ВЗЕМЕТЕ | Проверка за инициализация на приложението (използва се при първото стартиране) |
|
||||
| `/api/tags` | ВЗЕМЕТЕ | Тагове за модели, съвместими с Ollama (за клиенти на Ollama) |
|
||||
| `/api/рестартиране` | ПУБЛИКАЦИЯ | Задейства грациозно рестартиране на сървъра |
|
||||
| `/api/изключване` | ПУБЛИКАЦИЯ | Задействайте грациозно изключване на сървъра |
|
||||
|
||||
> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
|
||||
|
||||
---
|
||||
>**Забележка:**Тези крайни точки се използват вътрешно от системата или за съвместимост с клиента Ollama. Те обикновено не се извикват от крайните потребители.---
|
||||
|
||||
## Audio Transcription
|
||||
|
||||
@@ -339,69 +294,63 @@ These endpoints mirror Gemini's API format for clients that expect native Gemini
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
````
|
||||
|
||||
Transcribe audio files using Deepgram or AssemblyAI.
|
||||
Транскрибирайте аудио файлове с помощта на Deepgram или AssemblyAI.
|
||||
|
||||
**Request:**
|
||||
|
||||
```bash
|
||||
**Заявка:**```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"
|
||||
```
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@recording.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
|
||||
**Response:**
|
||||
````
|
||||
|
||||
```json
|
||||
**Отговор:**```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
**Поддържани доставчици:**`deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
**Поддържани формати:**`mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.---
|
||||
|
||||
## Ollama Compatibility
|
||||
|
||||
For clients that use Ollama's API format:
|
||||
За клиенти, които използват API формат на Ollama:```bash
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Requests are automatically translated between Ollama and internal formats.
|
||||
````
|
||||
|
||||
---
|
||||
Заявките се превеждат автоматично между Ollama и вътрешни формати.---
|
||||
|
||||
## Telemetry
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**Отговор:**```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
```
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -420,7 +369,7 @@ Content-Type: application/json
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -443,23 +392,21 @@ Content-Type: application/json
|
||||
|
||||
## Request Processing
|
||||
|
||||
1. Client sends request to `/v1/*`
|
||||
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
|
||||
3. Model is resolved (direct provider/model or alias/combo)
|
||||
4. Credentials selected from local DB with account availability filtering
|
||||
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
|
||||
6. Provider executor sends upstream request
|
||||
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
|
||||
8. Usage/logging recorded
|
||||
9. Fallback applies on errors according to combo rules
|
||||
1. Клиентът изпраща заявка до `/v1/*`
|
||||
2. Манипулаторът на маршрута извиква `handleChat`, `handleEmbedding`, `handleAudioTranscription` или `handleImageGeneration`
|
||||
3. Моделът е разрешен (директен доставчик/модел или псевдоним/комбо)
|
||||
4. Идентификационни данни, избрани от локална база данни с филтриране на наличността на акаунта
|
||||
5. За чат: `handleChatCore` — откриване на формат, превод, проверка на кеша, проверка на идемпотентност
|
||||
6. Изпълнителят на доставчика изпраща заявка нагоре по веригата
|
||||
7. Отговор, преведен обратно във формат на клиента (чат) или върнат такъв, какъвто е (вграждания/изображения/аудио)
|
||||
8. Записано използване/регистриране
|
||||
9. Резервният вариант се прилага при грешки според комбо правилата
|
||||
|
||||
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
Пълна справка за архитектурата: [`ARCHITECTURE.md`](ARCHITECTURE.md)---
|
||||
|
||||
## Authentication
|
||||
|
||||
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
|
||||
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
|
||||
- `requireLogin` toggleable via `/api/settings/require-login`
|
||||
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
|
||||
- Маршрутите на таблото за управление (`/dashboard/*`) използват бисквитка `auth_token`
|
||||
- Влизането използва хеш на запазена парола; връщане към `INITIAL_PASSWORD`
|
||||
- `requireLogin` може да се превключва чрез `/api/settings/require-login`
|
||||
- `/v1/*` маршрутите по избор изискват Bearer API ключ, когато `REQUIRE_API_KEY=true`
|
||||
|
||||
@@ -1,93 +1,83 @@
|
||||
# OmniRoute Architecture (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇮🇳 [in](../../in/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇮🇳 [hi](../../hi/docs/ARCHITECTURE.md) · 🇮🇳 [in](../../in/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md) · 🇹🇷 [tr](../../tr/docs/ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
_Last updated: 2026-03-28_
|
||||
_Последна актуализация: 2026-03-28_## Executive Summary
|
||||
|
||||
## Executive Summary
|
||||
OmniRoute е локален AI маршрутизиращ шлюз и табло за управление, изградено на Next.js.
|
||||
Той осигурява единична OpenAI-съвместима крайна точка (`/v1/*`) и маршрутизира трафик през множество доставчици нагоре по веригата с превод, резервен вариант, опресняване на токени и проследяване на използването.
|
||||
|
||||
OmniRoute is a local AI routing gateway and dashboard built on Next.js.
|
||||
It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking.
|
||||
Основни възможности:
|
||||
|
||||
Core capabilities:
|
||||
- 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/`)
|
||||
|
||||
- OpenAI-compatible API surface for CLI/tools (28 providers)
|
||||
- Request/response translation across provider formats
|
||||
- Model combo fallback (multi-model sequence)
|
||||
- Account-level fallback (multi-account per provider)
|
||||
- OAuth + API-key provider connection management
|
||||
- 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
|
||||
- IP allowlist/blocklist for API access control
|
||||
- Thinking budget management (passthrough/auto/custom/adaptive)
|
||||
- Global system prompt injection
|
||||
- Session tracking and fingerprinting
|
||||
- Per-account enhanced rate limiting with provider-specific profiles
|
||||
- Circuit breaker pattern for provider resilience
|
||||
- Anti-thundering herd protection with mutex locking
|
||||
- Signature-based request deduplication cache
|
||||
- Domain layer: model availability, cost rules, fallback policy, lockout policy
|
||||
- Domain state persistence (SQLite write-through cache for fallbacks, budgets, lockouts, circuit breakers)
|
||||
- Policy engine for centralized request evaluation (lockout → budget → fallback)
|
||||
- Request telemetry with p50/p95/p99 latency aggregation
|
||||
- Correlation ID (X-Request-Id) for end-to-end tracing
|
||||
- Compliance audit logging with opt-out per API key
|
||||
- Eval framework for LLM quality assurance
|
||||
- Resilience UI dashboard with real-time circuit breaker status
|
||||
- Modular OAuth providers (12 individual modules under `src/lib/oauth/providers/`)
|
||||
Основен модел на изпълнение:
|
||||
|
||||
Primary runtime model:
|
||||
|
||||
- Next.js app routes under `src/app/api/*` implement both dashboard APIs and compatibility APIs
|
||||
- A shared SSE/routing core in `src/sse/*` + `open-sse/*` handles provider execution, translation, streaming, fallback, and usage
|
||||
|
||||
## Scope and Boundaries
|
||||
- Маршрутите на приложението Next.js под `src/app/api/*` внедряват както API на таблото, така и API за съвместимост
|
||||
- Споделено SSE/маршрутизиращо ядро в `src/sse/*` + `open-sse/*` обработва изпълнението на доставчика, превода, стрийминг, резервен вариант и използване## Scope and Boundaries
|
||||
|
||||
### In Scope
|
||||
|
||||
- Local gateway runtime
|
||||
- Dashboard management APIs
|
||||
- Provider authentication and token refresh
|
||||
- Request translation and SSE streaming
|
||||
- Local state + usage persistence
|
||||
- Optional cloud sync orchestration
|
||||
- Време за изпълнение на локален шлюз
|
||||
- API за управление на таблото
|
||||
- Удостоверяване на доставчика и опресняване на токена
|
||||
- Заявка за превод и SSE стрийминг
|
||||
- Локално състояние + постоянство на използване
|
||||
- Допълнителна синхронизация в облака### Out of Scope
|
||||
|
||||
### Out of Scope
|
||||
- Внедряване на облачна услуга зад `NEXT_PUBLIC_CLOUD_URL`
|
||||
- SLA/контролна равнина на доставчика извън локалния процес
|
||||
- Самите външни CLI двоични файлове (Claude CLI, Codex CLI и т.н.)## Dashboard Surface (Current)
|
||||
|
||||
- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Provider SLA/control plane outside local process
|
||||
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
|
||||
Главни страници под `src/app/(dashboard)/dashboard/`:
|
||||
|
||||
## Dashboard Surface (Current)
|
||||
|
||||
Main pages under `src/app/(dashboard)/dashboard/`:
|
||||
|
||||
- `/dashboard` — quick start + provider overview
|
||||
- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint tabs
|
||||
- `/dashboard/providers` — provider connections and credentials
|
||||
- `/dashboard/combos` — combo strategies, templates, model routing rules
|
||||
- `/dashboard/costs` — cost aggregation and pricing visibility
|
||||
- `/dashboard/analytics` — usage analytics and evaluations
|
||||
- `/dashboard/limits` — quota/rate controls
|
||||
- `/dashboard/cli-tools` — CLI onboarding, runtime detection, config generation
|
||||
- `/dashboard/agents` — detected ACP agents + custom agent registration
|
||||
- `/dashboard/media` — image/video/music playground
|
||||
- `/dashboard/search-tools` — search provider testing and history
|
||||
- `/dashboard/health` — uptime, circuit breakers, rate limits
|
||||
- `/dashboard/logs` — request/proxy/audit/console logs
|
||||
- `/dashboard/settings` — system settings tabs (general, routing, combo defaults, etc.)
|
||||
- `/dashboard/api-manager` — API key lifecycle and model permissions
|
||||
|
||||
## High-Level System Context
|
||||
- `/dashboard` — бърз старт + преглед на доставчика
|
||||
- `/dashboard/endpoint` — крайна точка прокси + MCP + A2A + раздели за крайна точка на API
|
||||
- `/dashboard/providers` — връзки и идентификационни данни на доставчика
|
||||
- `/dashboard/combos` — комбинирани стратегии, шаблони, правила за маршрутизиране на модели
|
||||
- `/dashboard/costs` — агрегиране на разходите и видимост на цените
|
||||
- `/dashboard/analytics` — анализи и оценки на използването
|
||||
- `/dashboard/limits` — контроли на квоти/ставки
|
||||
- `/dashboard/cli-tools` — CLI включване, откриване по време на изпълнение, генериране на конфигурация
|
||||
- `/dashboard/agents` — открити ACP агенти + потребителска регистрация на агент
|
||||
- `/dashboard/media` — игрище за изображения/видео/музика
|
||||
- `/dashboard/search-tools` — тестване и история на доставчика на търсене
|
||||
- `/dashboard/health` — време на работа, прекъсвачи, ограничения на скоростта
|
||||
- `/dashboard/logs` — регистрационни файлове на заявка/прокси/одит/конзола
|
||||
- `/dashboard/settings` — раздели за системни настройки (общи, маршрутизиране, комбинирани настройки по подразбиране и т.н.)
|
||||
- `/dashboard/api-manager` — жизнен цикъл на API ключ и разрешения за модел## High-Level System Context
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -139,149 +129,139 @@ flowchart LR
|
||||
|
||||
## 1) API and Routing Layer (Next.js App Routes)
|
||||
|
||||
Main directories:
|
||||
Основни директории:
|
||||
|
||||
- `src/app/api/v1/*` and `src/app/api/v1beta/*` for compatibility APIs
|
||||
- `src/app/api/*` for management/configuration APIs
|
||||
- Next rewrites in `next.config.mjs` map `/v1/*` to `/api/v1/*`
|
||||
- `src/app/api/v1/*` и `src/app/api/v1beta/*` за API за съвместимост
|
||||
- `src/app/api/*` за API за управление/конфигуриране
|
||||
- Следващото пренаписване в `next.config.mjs` преобразува `/v1/*` в `/api/v1/*`
|
||||
|
||||
Important compatibility routes:
|
||||
Важни пътища за съвместимост:
|
||||
|
||||
- `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` — includes custom models with `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — embedding generation (6 providers)
|
||||
- `src/app/api/v1/images/generations/route.ts` — image generation (4+ providers incl. Antigravity/Nebius)
|
||||
- `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` — dedicated per-provider chat
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedicated per-provider embeddings
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedicated per-provider images
|
||||
- `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`
|
||||
|
||||
Management domains:
|
||||
Домейни за управление:
|
||||
|
||||
- Auth/settings: `src/app/api/auth/*`, `src/app/api/settings/*`
|
||||
- Providers/connections: `src/app/api/providers*`
|
||||
- Provider nodes: `src/app/api/provider-nodes*`
|
||||
- Custom models: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Model catalog: `src/app/api/models/route.ts` (GET)
|
||||
- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- Удостоверяване/настройки: `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/route.ts` (GET)
|
||||
- Прокси конфигурация: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- Keys/aliases/combos/pricing: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Usage: `src/app/api/usage/*`
|
||||
- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
||||
- CLI tooling helpers: `src/app/api/cli-tools/*`
|
||||
- IP filter: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- System prompt: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Sessions: `src/app/api/sessions` (GET)
|
||||
- Rate limits: `src/app/api/rate-limits` (GET)
|
||||
- Resilience: `src/app/api/resilience` (GET/PATCH) — provider profiles, circuit breaker, rate limit state
|
||||
- Resilience reset: `src/app/api/resilience/reset` (POST) — reset breakers + cooldowns
|
||||
- Cache stats: `src/app/api/cache/stats` (GET/DELETE)
|
||||
- Model availability: `src/app/api/models/availability` (GET/POST)
|
||||
- Telemetry: `src/app/api/telemetry/summary` (GET)
|
||||
- Budget: `src/app/api/usage/budget` (GET/POST)
|
||||
- Fallback chains: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Compliance audit: `src/app/api/compliance/audit-log` (GET)
|
||||
- Ключове/псевдоними/комбота/цени: `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` (GET/DELETE)
|
||||
- Наличност на модела: `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)
|
||||
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Policies: `src/app/api/policies` (GET/POST)
|
||||
- Правила: `src/app/api/policies` (GET/POST)## 2) SSE + Translation Core
|
||||
|
||||
## 2) SSE + Translation Core
|
||||
Основни модули на потока:
|
||||
|
||||
Main flow modules:
|
||||
- Запис: `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`
|
||||
|
||||
- Entry: `src/sse/handlers/chat.ts`
|
||||
- Core orchestration: `open-sse/handlers/chatCore.ts`
|
||||
- Provider execution adapters: `open-sse/executors/*`
|
||||
- Format detection/provider config: `open-sse/services/provider.ts`
|
||||
- Model parse/resolve: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
||||
- Account fallback logic: `open-sse/services/accountFallback.ts`
|
||||
- Translation registry: `open-sse/translator/index.ts`
|
||||
- Stream transformations: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
||||
- Usage extraction/normalization: `open-sse/utils/usageTracking.ts`
|
||||
- Think tag parser: `open-sse/utils/thinkTagParser.ts`
|
||||
- Embedding handler: `open-sse/handlers/embeddings.ts`
|
||||
- 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):
|
||||
- Избор/точкуване на акаунт: `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`
|
||||
|
||||
- Account selection/scoring: `open-sse/services/accountSelector.ts`
|
||||
- Context lifecycle management: `open-sse/services/contextManager.ts`
|
||||
- IP filter enforcement: `open-sse/services/ipFilter.ts`
|
||||
- Session tracking: `open-sse/services/sessionManager.ts`
|
||||
- Request deduplication: `open-sse/services/signatureCache.ts`
|
||||
- System prompt injection: `open-sse/services/systemPrompt.ts`
|
||||
- Thinking budget management: `open-sse/services/thinkingBudget.ts`
|
||||
- Wildcard model routing: `open-sse/services/wildcardRouter.ts`
|
||||
- Rate limit management: `open-sse/services/rateLimitManager.ts`
|
||||
- Circuit breaker: `open-sse/services/circuitBreaker.ts`
|
||||
Модули на ниво домейн:
|
||||
|
||||
Domain layer modules:
|
||||
- Наличност на модела: `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 за резервни вериги, бюджети, история на разходите, състояние на блокиране, прекъсвачи
|
||||
|
||||
- Model availability: `src/lib/domain/modelAvailability.ts`
|
||||
- Cost rules/budgets: `src/lib/domain/costRules.ts`
|
||||
- Fallback policy: `src/lib/domain/fallbackPolicy.ts`
|
||||
- Combo resolver: `src/lib/domain/comboResolver.ts`
|
||||
- Lockout policy: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Policy engine: `src/domain/policyEngine.ts` — centralized lockout → budget → fallback evaluation
|
||||
- Error codes catalog: `src/lib/domain/errorCodes.ts`
|
||||
- Request ID: `src/lib/domain/requestId.ts`
|
||||
- Fetch timeout: `src/lib/domain/fetchTimeout.ts`
|
||||
- Request telemetry: `src/lib/domain/requestTelemetry.ts`
|
||||
- Compliance/audit: `src/lib/domain/compliance/index.ts`
|
||||
- Eval runner: `src/lib/domain/evalRunner.ts`
|
||||
- Domain state persistence: `src/lib/db/domainState.ts` — SQLite CRUD for fallback chains, budgets, cost history, lockout state, circuit breakers
|
||||
Модули за доставчик на OAuth (12 отделни файла под `src/lib/oauth/providers/`):
|
||||
|
||||
OAuth provider modules (12 individual files under `src/lib/oauth/providers/`):
|
||||
- Индекс на регистъра: `src/lib/oauth/providers/index.ts`
|
||||
- Индивидуални доставчици: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Тънка обвивка: `src/lib/oauth/providers.ts` — повторно експортиране от отделни модули## 3) Persistence Layer
|
||||
|
||||
- Registry index: `src/lib/oauth/providers/index.ts`
|
||||
- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules
|
||||
Основно състояние DB (SQLite):
|
||||
|
||||
## 3) Persistence Layer
|
||||
- Основна информация: `src/lib/db/core.ts` (better-sqlite3, миграции, WAL)
|
||||
- Повторно експортиране на фасада: `src/lib/localDb.ts` (тънък слой за съвместимост за повикващите)
|
||||
- файл: `${DATA_DIR}/storage.sqlite` (или `$XDG_CONFIG_HOME/omniroute/storage.sqlite`, когато е зададено, иначе `~/.omniroute/storage.sqlite`)
|
||||
- обекти (таблици + KV пространства от имена): providerConnections, providerNodes, modelAliases, комбинации, apiKeys, настройки, ценообразуване,**customModels**,**proxyConfig**,**ipFilter**,**thinkingBudget**,**systemPrompt**
|
||||
|
||||
Primary state DB (SQLite):
|
||||
Устойчивост на употреба:
|
||||
|
||||
- Core infra: `src/lib/db/core.ts` (better-sqlite3, migrations, WAL)
|
||||
- Re-export facade: `src/lib/localDb.ts` (thin compatibility layer for callers)
|
||||
- file: `${DATA_DIR}/storage.sqlite` (or `$XDG_CONFIG_HOME/omniroute/storage.sqlite` when set, else `~/.omniroute/storage.sqlite`)
|
||||
- entities (tables + KV namespaces): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
||||
- фасада: `src/lib/usageDb.ts` (декомпозирани модули в `src/lib/usage/*`)
|
||||
- SQLite таблици в `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
|
||||
- незадължителните файлови артефакти остават за съвместимост/отстраняване на грешки (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `<repo>/logs/...`)
|
||||
- наследените JSON файлове се мигрират към SQLite чрез миграции при стартиране, когато има такива
|
||||
|
||||
Usage persistence:
|
||||
DB на състоянието на домейна (SQLite):
|
||||
|
||||
- facade: `src/lib/usageDb.ts` (decomposed modules in `src/lib/usage/*`)
|
||||
- SQLite tables in `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
|
||||
- optional file artifacts remain for compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `<repo>/logs/...`)
|
||||
- legacy JSON files are migrated to SQLite by startup migrations when present
|
||||
- `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) Auth + Security Surfaces
|
||||
|
||||
Domain State DB (SQLite):
|
||||
- Удостоверяване на бисквитките на таблото за управление: `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) Cloud Sync
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD operations for domain state
|
||||
- Tables (created in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Write-through cache pattern: in-memory Maps are authoritative at runtime; mutations are written synchronously to SQLite; state is restored from DB on cold start
|
||||
|
||||
## 4) Auth + Security Surfaces
|
||||
|
||||
- Dashboard cookie auth: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
||||
- API key generation/verification: `src/shared/utils/apiKey.ts`
|
||||
- Provider secrets persisted in `providerConnections` entries
|
||||
- Outbound proxy support via `open-sse/utils/proxyFetch.ts` (env vars) and `open-sse/utils/networkProxy.ts` (configurable per-provider or global)
|
||||
|
||||
## 5) Cloud Sync
|
||||
|
||||
- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
|
||||
- Periodic task: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Periodic task: `src/shared/services/modelSyncScheduler.ts`
|
||||
- Control route: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Request Lifecycle (`/v1/chat/completions`)
|
||||
- Инициализация на Scheduler: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
|
||||
- Периодична задача: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Периодична задача: `src/shared/services/modelSyncScheduler.ts`
|
||||
- Контролен маршрут: `src/app/api/sync/cloud/route.ts`## Request Lifecycle (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -358,9 +338,7 @@ flowchart TD
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics. Combo routing adds one extra guard: provider-scoped 400s such as upstream content-block and role-validation failures are treated as model-local failures so later combo targets can still run.
|
||||
|
||||
## OAuth Onboarding and Token Refresh Lifecycle
|
||||
Резервните решения се управляват от `open-sse/services/accountFallback.ts`, като се използват кодове за състояние и евристика за съобщения за грешка. Комбинираното маршрутизиране добавя един допълнителен предпазител: 400-те с обхват на доставчика, като неизправности при блокиране на съдържание нагоре и проверка на роли, се третират като неизправности в локален модел, така че по-късните комбинирани цели все още могат да се изпълняват.## OAuth Onboarding and Token Refresh Lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -390,9 +368,7 @@ sequenceDiagram
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
||||
|
||||
## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
Опресняването по време на трафик на живо се изпълнява вътре в `open-sse/handlers/chatCore.ts` чрез изпълнител `refreshCredentials()`.## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -424,9 +400,7 @@ sequenceDiagram
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
|
||||
|
||||
## Data Model and Storage Map
|
||||
Периодичното синхронизиране се задейства от „CloudSyncScheduler“, когато облакът е активиран.## Data Model and Storage Map
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
@@ -527,14 +501,12 @@ erDiagram
|
||||
}
|
||||
```
|
||||
|
||||
Physical storage files:
|
||||
Файлове за физическо съхранение:
|
||||
|
||||
- primary runtime DB: `${DATA_DIR}/storage.sqlite`
|
||||
- request log lines: `${DATA_DIR}/log.txt` (compat/debug artifact)
|
||||
- structured call payload archives: `${DATA_DIR}/call_logs/`
|
||||
- optional translator/request debug sessions: `<repo>/logs/...`
|
||||
|
||||
## Deployment Topology
|
||||
- основна база данни за изпълнение: `${DATA_DIR}/storage.sqlite`
|
||||
- Редове за заявка: `${DATA_DIR}/log.txt` (компат/дебъг артефакт)
|
||||
- структурирани архиви на полезния товар на повикванията: `${DATA_DIR}/call_logs/`
|
||||
- незадължителни сесии за преводач/заявка за отстраняване на грешки: `<repo>/logs/...`## Deployment Topology
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -569,246 +541,205 @@ flowchart LR
|
||||
|
||||
### Route and API Modules
|
||||
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibility APIs
|
||||
- `src/app/api/v1/providers/[provider]/*`: dedicated per-provider routes (chat, embeddings, images)
|
||||
- `src/app/api/providers*`: provider CRUD, validation, testing
|
||||
- `src/app/api/provider-nodes*`: custom compatible node management
|
||||
- `src/app/api/provider-models`: custom model management (CRUD)
|
||||
- `src/app/api/models/route.ts`: model catalog API (aliases + custom models)
|
||||
- `src/app/api/oauth/*`: OAuth/device-code flows
|
||||
- `src/app/api/keys*`: local API key lifecycle
|
||||
- `src/app/api/models/alias`: alias management
|
||||
- `src/app/api/combos*`: fallback combo management
|
||||
- `src/app/api/pricing`: pricing overrides for cost calculation
|
||||
- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST)
|
||||
- `src/app/api/usage/*`: usage and logs APIs
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers
|
||||
- `src/app/api/cli-tools/*`: local CLI config writers/checkers
|
||||
- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT)
|
||||
- `src/app/api/sessions`: active session listing (GET)
|
||||
- `src/app/api/rate-limits`: per-account rate limit status (GET)
|
||||
- `src/app/api/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/route.ts`: 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)### Routing and Execution Core
|
||||
|
||||
### Routing and Execution Core
|
||||
- `src/sse/handlers/chat.ts`: анализ на заявка, комбо обработка, цикъл за избор на акаунт
|
||||
- `open-sse/handlers/chatCore.ts`: превод, изпращане на изпълнителя, повторен опит/опресняване, настройка на потока
|
||||
- `open-sse/executors/*`: специфично за доставчика поведение на мрежа и формат### Translation Registry and Format Converters
|
||||
|
||||
- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop
|
||||
- `open-sse/handlers/chatCore.ts`: translation, executor dispatch, retry/refresh handling, stream setup
|
||||
- `open-sse/executors/*`: provider-specific network and format behavior
|
||||
- `open-sse/translator/index.ts`: регистър на преводачите и оркестрация
|
||||
- Заявка за преводачи: `open-sse/translator/request/*`
|
||||
- Преводачи на отговор: `open-sse/translator/response/*`
|
||||
- Форматни константи: `open-sse/translator/formats.ts`### Persistence
|
||||
|
||||
### Translation Registry and Format Converters
|
||||
- `src/lib/db/*`: постоянна конфигурация/състояние и устойчивост на домейн на SQLite
|
||||
- `src/lib/localDb.ts`: повторно експортиране на съвместимост за DB модули
|
||||
- `src/lib/usageDb.ts`: хронология на използването/фасада на регистрационните файлове на повикванията върху SQLite таблици## Provider Executor Coverage (Strategy Pattern)
|
||||
|
||||
- `open-sse/translator/index.ts`: translator registry and orchestration
|
||||
- Request translators: `open-sse/translator/request/*`
|
||||
- Response translators: `open-sse/translator/response/*`
|
||||
- Format constants: `open-sse/translator/formats.ts`
|
||||
Всеки доставчик има специализиран изпълнител, разширяващ `BaseExecutor` (в `open-sse/executors/base.ts`), който осигурява изграждане на URL адрес, изграждане на заглавка, повторен опит с експоненциално забавяне, кукички за опресняване на идентификационни данни и метода за оркестрация `execute()`.
|
||||
|
||||
### Persistence
|
||||
| Изпълнител | Доставчик(и) | Специална обработка |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
||||
| `Изпълнител по подразбиране` | OpenAI, Claude, Gemini, Qwen, Qoder, 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 токен |
|
||||
|
||||
- `src/lib/db/*`: persistent config/state and domain persistence on SQLite
|
||||
- `src/lib/localDb.ts`: compatibility re-export for DB modules
|
||||
- `src/lib/usageDb.ts`: usage history/call logs facade on top of SQLite tables
|
||||
Всички други доставчици (включително персонализирани съвместими възли) използват `DefaultExecutor`.## Provider Compatibility Matrix
|
||||
|
||||
## Provider Executor Coverage (Strategy Pattern)
|
||||
| Доставчик | Формат | Удостоверяване | Поток | Непоточно | Опресняване на токена | 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 | ✅ | ✅ | ✅ | ⚠️ По заявка |
|
||||
| Qoder | 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 ключ | ✅ | ✅ | ❌ | ❌ | ## Format Translation Coverage |
|
||||
|
||||
Each provider has a specialized executor extending `BaseExecutor` (in `open-sse/executors/base.ts`), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the `execute()` orchestration method.
|
||||
Откритите изходни формати включват:
|
||||
|
||||
| Executor | Provider(s) | Special Handling |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic URL/header config per provider |
|
||||
| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing |
|
||||
| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort |
|
||||
| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum |
|
||||
| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
|
||||
| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle |
|
||||
- `опенай`
|
||||
- `openaj-отговори`
|
||||
- „Клод“.
|
||||
- "близнаци".
|
||||
|
||||
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
|
||||
Целевите формати включват:
|
||||
|
||||
## Provider Compatibility Matrix
|
||||
- OpenAI чат/Отговори
|
||||
- Клод
|
||||
- Gemini/Gemini-CLI/Антигравитационен плик
|
||||
- Киро
|
||||
- Курсор
|
||||
|
||||
| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API |
|
||||
| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ |
|
||||
| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only |
|
||||
| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API |
|
||||
| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits |
|
||||
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots |
|
||||
| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ |
|
||||
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits |
|
||||
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request |
|
||||
| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ Per request |
|
||||
| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Perplexity | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Together AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
## Format Translation Coverage
|
||||
|
||||
Detected source formats include:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
Target formats include:
|
||||
|
||||
- OpenAI chat/Responses
|
||||
- Claude
|
||||
- Gemini/Gemini-CLI/Antigravity envelope
|
||||
- Kiro
|
||||
- Cursor
|
||||
|
||||
Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
|
||||
|
||||
```
|
||||
Преводите използват**OpenAI като хъб формат**— всички реализации преминават през OpenAI като междинен:```
|
||||
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
|
||||
-**Дефектиране на отговора**— Премахва нестандартните полета от отговорите във формат OpenAI (както стрийминг, така и без стрийминг), за да се гарантира стриктно съответствие с SDK
|
||||
-**Нормализиране на ролята**— Преобразува `developer` → `system` за цели, които не са OpenAI; обединява `system` → `user` за модели, които отхвърлят системната роля (GLM, ERNIE)
|
||||
-**Извличане на мислен етикет**— Анализира `<think>...</think>` блокове от съдържание в полето `reasoning_content`
|
||||
-**Структуриран изход**— Преобразува OpenAI `response_format.json_schema` в `responseMimeType` + `responseSchema` на Gemini## Supported API Endpoints
|
||||
|
||||
| Endpoint | Format | Handler |
|
||||
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------- |
|
||||
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Claude Messages | Same handler (auto-detected) |
|
||||
| `POST /v1/responses` | OpenAI Responses | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | Model listing | API route |
|
||||
| `POST /v1/images/generations` | OpenAI Images | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | Model listing | API route |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicated per-provider with model validation |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicated per-provider with model validation |
|
||||
| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Dedicated per-provider with model validation |
|
||||
| `POST /v1/messages/count_tokens` | Claude Token Count | API route |
|
||||
| `GET /v1/models` | OpenAI Models list | API route (chat + embedding + image + custom models) |
|
||||
| `GET /api/models/catalog` | Catalog | All models grouped by provider + type |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Gemini native | API route |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Network proxy configuration |
|
||||
| `POST /api/settings/proxy/test` | Proxy Connectivity | Proxy health/connectivity test endpoint |
|
||||
| `GET/POST/DELETE /api/provider-models` | Provider Models | Provider model metadata backing custom and managed available models |
|
||||
| Крайна точка | Формат | Манипулатор |
|
||||
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------ |
|
||||
| `POST /v1/chat/completions` | OpenAI чат | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Съобщения на Клод | Същият манипулатор (автоматично разпознат) |
|
||||
| `POST /v1/responses` | OpenAI отговори | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/вграждания` | OpenAI вграждания | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/вграждания` | Списък на модели | 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` | Модели на доставчици | Метаданни за модела на доставчика, поддържащи персонализирани и управлявани налични модели |## Bypass Handler
|
||||
|
||||
## Bypass Handler
|
||||
Обходният манипулатор (`open-sse/utils/bypassHandler.ts`) прихваща известни заявки за "изхвърляне" от Claude CLI - пингове за загряване, извличане на заглавия и броене на токени - и връща**фалшив отговор**, без да консумира токени на доставчика нагоре по веригата. Това се задейства само когато `User-Agent` съдържа `claude-cli`.## Request Logger Pipeline
|
||||
|
||||
The bypass handler (`open-sse/utils/bypassHandler.ts`) intercepts known "throwaway" requests from Claude CLI — warmup pings, title extractions, and token counts — and returns a **fake response** without consuming upstream provider tokens. This is triggered only when `User-Agent` contains `claude-cli`.
|
||||
|
||||
## Request Logger Pipeline
|
||||
|
||||
The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
Регистраторът на заявки (`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
|
||||
```
|
||||
````
|
||||
|
||||
Files are written to `<repo>/logs/<session>/` for each request session.
|
||||
|
||||
## Failure Modes and Resilience
|
||||
Файловете се записват в `<repo>/logs/<session>/` за всяка сесия на заявка.## Failure Modes and Resilience
|
||||
|
||||
## 1) Account/Provider Availability
|
||||
|
||||
- provider account cooldown on transient/rate/auth errors
|
||||
- account fallback before failing request
|
||||
- combo model fallback when current model/provider path is exhausted
|
||||
- изчакване на акаунта на доставчика при преходни/скоростни/удостоверителни грешки
|
||||
- резервен акаунт преди неуспешна заявка
|
||||
- резервен комбиниран модел, когато пътят на текущия модел/доставчик е изчерпан## 2) Token Expiry
|
||||
|
||||
## 2) Token Expiry
|
||||
- предварителна проверка и опресняване с повторен опит за опресняващи доставчици
|
||||
- 401/403 повторен опит след опит за опресняване в основния път## 3) Stream Safety
|
||||
|
||||
- pre-check and refresh with retry for refreshable providers
|
||||
- 401/403 retry after refresh attempt in core path
|
||||
- контролер на потоци с прекъсване на връзката
|
||||
- поток за превод с промиване в края на потока и обработка на `[DONE]`
|
||||
- резервна оценка на използването, когато липсват метаданни за използване на доставчика## 4) Cloud Sync Degradation
|
||||
|
||||
## 3) Stream Safety
|
||||
- появяват се грешки при синхронизиране, но локалното изпълнение продължава
|
||||
- планировчикът има логика с възможност за повторен опит, но периодичното изпълнение в момента извиква синхронизиране с един опит по подразбиране## 5) Data Integrity
|
||||
|
||||
- disconnect-aware stream controller
|
||||
- translation stream with end-of-stream flush and `[DONE]` handling
|
||||
- usage estimation fallback when provider usage metadata is missing
|
||||
- Миграции на SQLite схема и кукички за автоматично надграждане при стартиране
|
||||
- наследен JSON → път за съвместимост на миграцията на SQLite## Observability and Operational Signals
|
||||
|
||||
## 4) Cloud Sync Degradation
|
||||
Източници на видимост по време на изпълнение:
|
||||
|
||||
- sync errors are surfaced but local runtime continues
|
||||
- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default
|
||||
- регистрационни файлове на конзолата от `src/sse/utils/logger.ts`
|
||||
- агрегати за използване на заявка в SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- четиристепенно улавяне на подробен полезен товар в SQLite (`request_detail_logs`), когато `settings.detailed_logs_enabled=true`
|
||||
- текстов регистър на състоянието на заявката в `log.txt` (по избор/compat)
|
||||
- незадължителни дълбоки регистрационни файлове за заявка/превод под `logs/`, когато `ENABLE_REQUEST_LOGS=true`
|
||||
- крайни точки за използване на таблото за управление (`/api/usage/*`) за използване на UI
|
||||
|
||||
## 5) Data Integrity
|
||||
Подробно улавяне на полезен товар на заявка съхранява до четири етапа на полезен товар в JSON на маршрутизирано повикване:
|
||||
|
||||
- SQLite schema migrations and auto-upgrade hooks at startup
|
||||
- legacy JSON → SQLite migration compatibility path
|
||||
- необработена заявка, получена от клиента
|
||||
- преведена заявка, действително изпратена нагоре
|
||||
- отговор на доставчика, реконструиран като JSON; поточно предаваните отговори се уплътняват до крайното резюме плюс метаданни на потока
|
||||
- окончателен клиентски отговор, върнат от OmniRoute; поточно предаваните отговори се съхраняват в същата компактна обобщена форма## Security-Sensitive Boundaries
|
||||
|
||||
## Observability and Operational Signals
|
||||
- JWT тайна (`JWT_SECRET`) защитава проверката/подписването на бисквитките на сесията на таблото за управление
|
||||
- Първоначалната парола за зареждане (`INITIAL_PASSWORD`) трябва да бъде изрично конфигурирана за осигуряване при първо стартиране
|
||||
- API ключ HMAC тайна (`API_KEY_SECRET`) защитава генерирания локален формат на API ключ
|
||||
- Тайните на доставчика (API ключове/токени) се съхраняват в локалната база данни и трябва да бъдат защитени на ниво файлова система
|
||||
- Крайните точки за синхронизиране в облак разчитат на удостоверяване на API ключ + семантика на идентификатор на машина## Environment and Runtime Matrix
|
||||
|
||||
Runtime visibility sources:
|
||||
Променливите на средата, използвани активно от кода:
|
||||
|
||||
- console logs from `src/sse/utils/logger.ts`
|
||||
- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- four-stage detailed payload captures in SQLite (`request_detail_logs`) when `settings.detailed_logs_enabled=true`
|
||||
- textual request status log in `log.txt` (optional/compat)
|
||||
- optional deep request/translation logs under `logs/` when `ENABLE_REQUEST_LOGS=true`
|
||||
- dashboard usage endpoints (`/api/usage/*`) for UI consumption
|
||||
- Приложение/удостоверяване: `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`## Known Architectural Notes
|
||||
|
||||
Detailed request payload capture stores up to four JSON payload stages per routed call:
|
||||
1. `usageDb` и `localDb` споделят една и съща основна политика за директория (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) с мигриране на наследени файлове.
|
||||
2. `/api/v1/route.ts` делегира на същия унифициран конструктор на каталог, използван от `/api/v1/models` (`src/app/api/v1/models/catalog.ts`), за да се избегне семантично отклонение.
|
||||
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:unit`. Изходният код под `src/` е**TypeScript**(`.ts`/`.tsx`); работното пространство `open-sse/` остава JavaScript (`.js`).
|
||||
8. Страницата с настройки е организирана в 5 раздела: Сигурност, Маршрутизация (6 глобални стратегии: първо запълване, кръгова система, p2c, произволна, най-малко използвана, оптимизирана по отношение на разходите), Устойчивост (ограничения на скоростта за редактиране, прекъсвач, политики), AI (мислещ бюджет, системна подкана, кеш за подкана), Разширени (прокси).## Operational Verification Checklist
|
||||
|
||||
- raw request received from the client
|
||||
- translated request actually sent upstream
|
||||
- provider response reconstructed as JSON; streamed responses are compacted to the final summary plus stream metadata
|
||||
- final client response returned by OmniRoute; streamed responses are stored in the same compact summary form
|
||||
|
||||
## Security-Sensitive Boundaries
|
||||
|
||||
- JWT secret (`JWT_SECRET`) secures dashboard session cookie verification/signing
|
||||
- Initial password bootstrap (`INITIAL_PASSWORD`) should be explicitly configured for first-run provisioning
|
||||
- API key HMAC secret (`API_KEY_SECRET`) secures generated local API key format
|
||||
- Provider secrets (API keys/tokens) are persisted in local DB and should be protected at filesystem level
|
||||
- Cloud sync endpoints rely on API key auth + machine id semantics
|
||||
|
||||
## Environment and Runtime Matrix
|
||||
|
||||
Environment variables actively used by code:
|
||||
|
||||
- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD`
|
||||
- Storage: `DATA_DIR`
|
||||
- Compatible node behavior: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Optional storage base override (Linux/macOS when `DATA_DIR` unset): `XDG_CONFIG_HOME`
|
||||
- Security hashing: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
||||
- Logging: `ENABLE_REQUEST_LOGS`
|
||||
- Sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and lowercase variants
|
||||
- SOCKS5 feature flags: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Platform/runtime helpers (not app-specific config): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
|
||||
|
||||
## Known Architectural Notes
|
||||
|
||||
1. `usageDb` and `localDb` share the same base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) with legacy file migration.
|
||||
2. `/api/v1/route.ts` delegates to the same unified catalog builder used by `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) to avoid semantic drift.
|
||||
3. Request logger writes full headers/body when enabled; treat log directory as sensitive.
|
||||
4. Cloud behavior depends on correct `NEXT_PUBLIC_BASE_URL` and cloud endpoint reachability.
|
||||
5. The `open-sse/` directory is published as the `@omniroute/open-sse` **npm workspace package**. Source code imports it via `@omniroute/open-sse/...` (resolved by Next.js `transpilePackages`). File paths in this document still use the directory name `open-sse/` for consistency.
|
||||
6. Charts in the dashboard use **Recharts** (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates).
|
||||
7. E2E tests use **Playwright** (`tests/e2e/`), run via `npm run test:e2e`. Unit tests use **Node.js test runner** (`tests/unit/`), run via `npm run test:unit`. Source code under `src/` is **TypeScript** (`.ts`/`.tsx`); the `open-sse/` workspace remains JavaScript (`.js`).
|
||||
8. Settings page is organized into 5 tabs: Security, Routing (6 global strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized), Resilience (editable rate limits, circuit breaker, policies), AI (thinking budget, system prompt, prompt cache), Advanced (proxy).
|
||||
|
||||
## Operational Verification Checklist
|
||||
|
||||
- Build from source: `npm run build`
|
||||
- Build Docker image: `docker build -t omniroute .`
|
||||
- Start service and verify:
|
||||
- Изграждане от източник: `npm run build`
|
||||
- Изграждане на Docker изображение: `docker build -t omniroute .`
|
||||
- Стартирайте услугата и проверете:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- CLI target base URL should be `http://<host>:20128/v1` when `PORT=20128`
|
||||
- CLI целевият базов URL трябва да бъде `http://<host>:20128/v1`, когато `PORT=20128`
|
||||
|
||||
@@ -1,45 +1,32 @@
|
||||
# OmniRoute Auto-Combo Engine (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [hi](../../hi/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md) · 🇹🇷 [tr](../../tr/docs/AUTO-COMBO.md)
|
||||
|
||||
---
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
> Вериги от самоуправляващи се модели с адаптивно оценяване## How It Works
|
||||
|
||||
## How It Works
|
||||
Auto-Combo Engine динамично избира най-добрия доставчик/модел за всяка заявка с помощта на**6-факторна функция за оценяване**:
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
| Фактор | Тегло | Описание |
|
||||
| :--------- | :---- | :--------------------------------------------------- | ------------- |
|
||||
| Квота | 0,20 | Оставащ капацитет [0..1] |
|
||||
| Здраве | 0,25 | Прекъсвач: ЗАТВОРЕНО=1.0, ПОЛОВИНА=0.5, ОТВОРЕНО=0.0 |
|
||||
| CostInv | 0,20 | Обратна цена (по-евтино = по-висок резултат) |
|
||||
| LatencyInv | 0,15 | Обратна p95 латентност (по-бързо = по-високо) |
|
||||
| TaskFit | 0,10 | Модел × фитнес резултат за тип задача |
|
||||
| Стабилност | 0,10 | Ниска вариация в латентността/грешки | ## Mode Packs |
|
||||
|
||||
| Factor | Weight | Description |
|
||||
| :--------- | :----- | :---------------------------------------------- |
|
||||
| Quota | 0.20 | Remaining capacity [0..1] |
|
||||
| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
|
||||
| CostInv | 0.20 | Inverse cost (cheaper = higher score) |
|
||||
| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) |
|
||||
| TaskFit | 0.10 | Model × task type fitness score |
|
||||
| Stability | 0.10 | Low variance in latency/errors |
|
||||
| Пакет | Фокус | Ключово тегло |
|
||||
| :------------------------------ | :-------------- | :--------------- | --------------- |
|
||||
| 🚀**Изпращайте бързо** | Скорост | latencyInv: 0,35 |
|
||||
| 💰**Икономия на разходи** | Икономика | costInv: 0,40 |
|
||||
| 🎯**Качеството на първо място** | Най-добър модел | taskFit: 0,40 |
|
||||
| 📡**Офлайн приятелски** | Наличност | квота: 0,40 | ## Self-Healing |
|
||||
|
||||
## Mode Packs
|
||||
-**Временно изключване**: Резултат < 0,2 → изключено за 5 минути (прогресивно забавяне, максимум 30 минути) -**Информация за прекъсвач**: ОТВОРЕНО → автоматично изключване; HALF_OPEN → заявки за сонда -**Режим на инцидент**: >50% ОТВОРЕНО → дезактивиране на изследването, увеличаване на стабилността -**Възстановяване на охлаждане**: След изключване, първата заявка е "сонда" с намалено време за изчакване## Bandit Exploration
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
5% от заявките (с възможност за конфигуриране) се насочват към произволни доставчици за проучване. Деактивиран в режим на инцидент.## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
@@ -53,15 +40,13 @@ curl http://localhost:20128/api/combos/auto
|
||||
|
||||
## Task Fitness
|
||||
|
||||
30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score).
|
||||
30+ модела, отбелязани в 6 типа задачи („кодиране“, „преглед“, „планиране“, „анализ“, „отстраняване на грешки“, „документация“). Поддържа шаблони със заместващи знаци (напр. „\*-кодер“ → висок резултат на кодиране).## Files
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| :------------------------------------------- | :------------------------------------ |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
|
||||
| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles |
|
||||
| `src/app/api/combos/auto/route.ts` | REST API |
|
||||
| Файл | Цел |
|
||||
| :------------------------------------------- | :------------------------------------------- |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | Функция за точкуване и нормализиране на пула |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | Модел × търсене на фитнес задача |
|
||||
| `open-sse/services/autoCombo/engine.ts` | Логика на подбора, бандит, бюджетна граница |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | Изключване, сонди, режим на инцидент |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 тегловни профила |
|
||||
| `src/app/api/combos/auto/route.ts` | REST API |
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# CLI Tools Setup Guide — OmniRoute (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [hi](../../hi/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md) · 🇹🇷 [tr](../../tr/docs/CLI-TOOLS.md)
|
||||
|
||||
---
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
Това ръководство обяснява как да инсталирате и конфигурирате всички поддържани CLI инструменти за AI кодиране
|
||||
да използвате**OmniRoute**като унифициран бекенд, който ви дава централизирано управление на ключове,
|
||||
проследяване на разходите, превключване на модели и регистриране на заявки във всеки инструмент.---
|
||||
|
||||
## How It Works
|
||||
|
||||
@@ -22,118 +20,113 @@ Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilo
|
||||
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
**Ползи:**
|
||||
|
||||
- One API key to manage all tools
|
||||
- Cost tracking across all CLIs in the dashboard
|
||||
- Model switching without reconfiguring every tool
|
||||
- Works locally and on remote servers (VPS)
|
||||
|
||||
---
|
||||
- Един API ключ за управление на всички инструменти
|
||||
- Проследяване на разходите във всички CLI в таблото за управление
|
||||
- Превключване на модел без преконфигуриране на всеки инструмент
|
||||
- Работи локално и на отдалечени сървъри (VPS)---
|
||||
|
||||
## Supported Tools (Dashboard Source of Truth)
|
||||
|
||||
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
|
||||
Current list (v3.0.0-rc.16):
|
||||
Картите на таблото за управление в `/dashboard/cli-tools` се генерират от `src/shared/constants/cliTools.ts`.
|
||||
Текущ списък (v3.0.0-rc.16):
|
||||
|
||||
| Tool | ID | Command | Setup Mode | Install Method |
|
||||
| ------------------ | ------------- | ---------- | ---------- | -------------- |
|
||||
| **Claude Code** | `claude` | `claude` | env | npm |
|
||||
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
|
||||
| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
|
||||
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
|
||||
| **Cursor** | `cursor` | app | guide | desktop app |
|
||||
| **Cline** | `cline` | `cline` | custom | npm |
|
||||
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
|
||||
| **Continue** | `continue` | extension | guide | VS Code |
|
||||
| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
|
||||
| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
|
||||
| **OpenCode** | `opencode` | `opencode` | guide | npm |
|
||||
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
|
||||
| Инструмент | ID | Команда | Режим на настройка | Метод на инсталиране |
|
||||
| ------------------ | ---------------- | -------------- | ------------------ | -------------------- | -------------------------------------------- |
|
||||
| **Клод Код** | `клод` | `клод` | env | npm |
|
||||
| **OpenAI Codex** | `кодекс` | `кодекс` | обичай | npm |
|
||||
| **Фабричен дроид** | `дроид` | `дроид` | обичай | в пакет/CLI |
|
||||
| **OpenClaw** | `openclaw` | `openclaw` | обичай | в пакет/CLI |
|
||||
| **Курсор** | `курсор` | приложение | ръководство | настолно приложение |
|
||||
| **Клайн** | `cline` | `cline` | обичай | npm |
|
||||
| **Kilo Code** | `килограм` | `килокод` | обичай | npm |
|
||||
| **Продължи** | `продължи` | разширение | ръководство | VS код |
|
||||
| **Антигравитация** | `антигравитация` | вътрешен | митм | OmniRoute |
|
||||
| **GitHub Copilot** | `втори пилот` | разширение | обичай | VS код |
|
||||
| **OpenCode** | `отворен код` | `отворен код` | ръководство | npm |
|
||||
| **Киро AI** | `киро` | приложение/кли | митм | работен плот/CLI | ### CLI fingerprint sync (Agents + Settings) |
|
||||
|
||||
### CLI fingerprint sync (Agents + Settings)
|
||||
`/dashboard/agents` и `Settings > CLI Fingerprint` използват `src/shared/constants/cliCompatProviders.ts`.
|
||||
Това поддържа идентификаторите на доставчици в съответствие с CLI картите и наследените идентификатори.
|
||||
|
||||
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
|
||||
This keeps provider IDs aligned with CLI cards and legacy IDs.
|
||||
| CLI ID | ID на доставчика на пръстови отпечатъци |
|
||||
| ---------------------------------------------------------------------------------------------------- | --------------------------------------- |
|
||||
| `килограм` | `килокод` |
|
||||
| `втори пилот` | `github` |
|
||||
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | същия ID |
|
||||
|
||||
| CLI ID | Fingerprint Provider ID |
|
||||
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| `kilo` | `kilocode` |
|
||||
| `copilot` | `github` |
|
||||
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
|
||||
|
||||
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
|
||||
|
||||
---
|
||||
Наследените идентификатори все още се приемат за съвместимост: `copilot`, `kimi-coding`, `qwen`.---
|
||||
|
||||
## Step 1 — Get an OmniRoute API Key
|
||||
|
||||
1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`)
|
||||
2. Click **Create API Key**
|
||||
3. Give it a name (e.g. `cli-tools`) and select all permissions
|
||||
4. Copy the key — you'll need it for every CLI below
|
||||
1. Отворете таблото за управление на OmniRoute →**API Manager**(`/dashboard/api-manager`)
|
||||
2. Щракнете върху**Създаване на API ключ**
|
||||
3. Дайте му име (напр. `cli-tools`) и изберете всички разрешения
|
||||
4. Копирайте ключа — ще ви трябва за всеки CLI по-долу
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
> Вашият ключ изглежда така: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`---
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
Всички базирани на npm инструменти изискват Node.js 18+:```bash
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
|
||||
npm install -g @openai/codex
|
||||
|
||||
# OpenCode
|
||||
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
|
||||
npm install -g kilocode
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
|
||||
**Verify:**
|
||||
````
|
||||
|
||||
```bash
|
||||
**Потвърдете:**```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
opencode --version # x.x.x
|
||||
cline --version # 2.x.x
|
||||
kilocode --version # x.x.x (or: kilo --version)
|
||||
kiro-cli --version # 1.x.x
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Set Global Environment Variables
|
||||
|
||||
Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
|
||||
Добавете към `~/.bashrc` (или `~/.zshrc`), след което стартирайте `source ~/.bashrc`:```bash
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
````
|
||||
|
||||
---
|
||||
> За**отдалечен сървър**заменете `localhost:20128` с IP адреса на сървъра или домейна,
|
||||
> напр. `http://192.168.0.15:20128`.---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
@@ -150,11 +143,9 @@ mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
````
|
||||
|
||||
**Test:** `claude "say hello"`
|
||||
|
||||
---
|
||||
**Тест:**`claude "кажи здравей"`---
|
||||
|
||||
### OpenAI Codex
|
||||
|
||||
@@ -166,9 +157,7 @@ apiBaseUrl: http://localhost:20128/v1
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
**Тест:**`кодекс "колко е 2+2?"`---
|
||||
|
||||
### OpenCode
|
||||
|
||||
@@ -180,57 +169,45 @@ api_key = "sk-your-omniroute-key"
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
**Тест:**`отворен код`---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
**CLI режим:**```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"apiProvider": "openai",
|
||||
"openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"openAiApiKey": "sk-your-omniroute-key"
|
||||
"apiProvider": "openai",
|
||||
"openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"openAiApiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**VS Code mode:**
|
||||
Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
|
||||
````
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
|
||||
**VS кодов режим:**
|
||||
Настройки на разширението на Cline → Доставчик на API: `Съвместим с OpenAI` → Основен URL: `http://localhost:20128/v1`
|
||||
|
||||
---
|
||||
Или използвайте таблото OmniRoute →**CLI Tools → Cline → Apply Config**.---
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
**CLI режим:**```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
````
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
**Настройки на VS кода:**```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
````
|
||||
|
||||
---
|
||||
Или използвайте таблото OmniRoute →**CLI Tools → KiloCode → Apply Config**.---
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
Редактирайте `~/.continue/config.yaml`:```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
@@ -238,11 +215,9 @@ models:
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
````
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
Рестартирайте VS Code след редактиране.---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
@@ -259,65 +234,55 @@ kiro-cli status
|
||||
|
||||
### Cursor (Desktop App)
|
||||
|
||||
> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
|
||||
> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
|
||||
> **Забележка:**Cursor маршрутизира заявките през своя облак. За интеграция на OmniRoute,
|
||||
> активирайте**Крайна точка в облака**в настройките на OmniRoute и използвайте URL адреса на обществения си домейн.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
Чрез GUI:**Настройки → Модели → OpenAI API ключ**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
|
||||
---
|
||||
- Основен URL адрес: `https://your-domain.com/v1`
|
||||
- API ключ: вашият OmniRoute ключ---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
Таблото OmniRoute автоматизира конфигурацията за повечето инструменти:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
1. Отидете на `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Разгънете произволна карта с инструменти
|
||||
3. Изберете вашия API ключ от падащото меню
|
||||
4. Щракнете върху**Apply Config**(ако инструментът бъде открит като инсталиран)
|
||||
5. Или копирайте ръчно генерирания конфигурационен фрагмент---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
**Droid**и**OpenClaw**са AI агенти, вградени директно в OmniRoute — не е необходима инсталация.
|
||||
Те се изпълняват като вътрешни маршрути и автоматично използват модела на OmniRoute.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
- Достъп: `http://localhost:20128/dashboard/agents`
|
||||
- Конфигуриране: същите комбинации и доставчици като всички други инструменти
|
||||
- Не се изисква инсталиране на API ключ или CLI---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | Standard chat (all providers) | All modern tools |
|
||||
| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows |
|
||||
| `/v1/completions` | Legacy text completions | Older tools using `prompt:` |
|
||||
| `/v1/embeddings` | Text embeddings | RAG, search |
|
||||
| `/v1/images/generations` | Image generation | DALL-E, Flux, etc. |
|
||||
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
|
||||
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
|
||||
|
||||
---
|
||||
| Крайна точка | Описание | Използвайте за |
|
||||
| -------------------------- | ---------------------------------- | ------------------------------------------ | --- |
|
||||
| `/v1/chat/completions` | Стандартен чат (всички доставчици) | Всички съвременни инструменти |
|
||||
| `/v1/отговори` | API за отговори (формат OpenAI) | Codex, агентски работни процеси |
|
||||
| `/v1/завършвания` | Наследени довършвания на текст | По-стари инструменти, използващи `prompt:` |
|
||||
| `/v1/вграждания` | Вграждане на текст | RAG, търсене |
|
||||
| `/v1/images/generations` | Генериране на изображения | DALL-E, Flux и др. |
|
||||
| `/v1/audio/speech` | Преобразуване на текст в реч | ElevenLabs, OpenAI TTS |
|
||||
| `/v1/audio/transcriptions` | Преобразуване на реч в текст | Deepgram, AssemblyAI | --- |
|
||||
|
||||
## Отстраняване на проблеми
|
||||
|
||||
| Error | Cause | Fix |
|
||||
| ------------------------- | ----------------------- | ------------------------------------------ |
|
||||
| `Connection refused` | OmniRoute not running | `pm2 start omniroute` |
|
||||
| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` |
|
||||
| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` |
|
||||
| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` |
|
||||
| CLI shows "not installed" | Binary not in PATH | Check `which <command>` |
|
||||
| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
|
||||
|
||||
---
|
||||
| Грешка | Причина | Поправете |
|
||||
| ------------------------------- | ----------------------------------------- | -------------------------------------------------------- | --- |
|
||||
| `Връзката е отказана` | OmniRoute не работи | `pm2 стартиране на omniroute` |
|
||||
| „401 неразрешено“ | Грешен API ключ | Проверете в `/dashboard/api-manager` |
|
||||
| `Няма конфигурирана комбинация` | Няма активна комбинация за маршрутизиране | Настройте в `/dashboard/combos` |
|
||||
| `невалиден модел` | Моделът не е в каталога | Използвайте `auto` или маркирайте `/dashboard/providers` |
|
||||
| CLI показва „не е инсталирано“ | Двоичният файл не е в PATH | Проверете `коя <команда>` |
|
||||
| `kiro-cli: не е намерено` | Не е в PATH | `export PATH="$HOME/.local/bin:$PATH"` | --- |
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
# omniroute — Codebase Documentation (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [hi](../../hi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇷 [tr](../../tr/docs/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
---
|
||||
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
---
|
||||
> Изчерпателно, удобно за начинаещи ръководство за**omniroute**мултипровайдерен AI прокси рутер.---
|
||||
|
||||
## 1. What Is omniroute?
|
||||
|
||||
omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem:
|
||||
omniroute е**прокси рутер**, който се намира между AI клиенти (Claude CLI, Codex, Cursor IDE и др.) и AI доставчици (Anthropic, Google, OpenAI, AWS, GitHub и др.). Решава един голям проблем:
|
||||
|
||||
> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
|
||||
> **Различните AI клиенти говорят различни „езици“ (API формати) и различните доставчици на AI също очакват различни „езици“.**omniroute превежда автоматично между тях.
|
||||
|
||||
Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate.
|
||||
|
||||
---
|
||||
Мислете за това като за универсален преводач в Обединените нации - всеки делегат може да говори всеки език и преводачът го преобразува за всеки друг делегат.---
|
||||
|
||||
## 2. Architecture Overview
|
||||
|
||||
@@ -65,44 +61,43 @@ graph LR
|
||||
|
||||
### Core Principle: Hub-and-Spoke Translation
|
||||
|
||||
All format translation passes through **OpenAI format as the hub**:
|
||||
Всички преводи на формати преминават през**OpenAI формат като център**:```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
This means you only need **N translators** (one per format) instead of **N²** (every pair).
|
||||
|
||||
---
|
||||
Това означава, че имате нужда само от**N преводачи**(по един на формат) вместо от**N²**(всяка двойка).---
|
||||
|
||||
## 3. Project Structure
|
||||
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
├── 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
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -110,18 +105,16 @@ omniroute/
|
||||
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
The **single source of truth** for all provider configuration.
|
||||
**Единственият източник на истина**за всички конфигурации на доставчика.
|
||||
|
||||
| File | Purpose |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
|
||||
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
|
||||
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
|
||||
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
|
||||
|
||||
#### Credential Loading Flow
|
||||
| Файл | Цел |
|
||||
| ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `константи.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 (име, размер, семейство, квантуване). |#### Credential Loading Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -140,24 +133,22 @@ flowchart TD
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Executors (`open-sse/executors/`)
|
||||
|
||||
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
|
||||
|
||||
```mermaid
|
||||
Изпълнителите капсулират**специфична за доставчика логика**, използвайки**Стратегически модел**. Всеки изпълнител замества основните методи, ако е необходимо.```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 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()
|
||||
@@ -194,34 +185,31 @@ classDiagram
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| Executor | Provider | Key Specializations |
|
||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers |
|
||||
| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") |
|
||||
| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
|
||||
| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh |
|
||||
| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking |
|
||||
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
|
||||
| `index.ts` | — | Factory: maps provider name → executor class, with default fallback |
|
||||
````
|
||||
|
||||
---
|
||||
| Изпълнител | Доставчик | Ключови специализации |
|
||||
| ---------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `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 Handlers (`open-sse/handlers/`)
|
||||
|
||||
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
|
||||
**Слоят за оркестрация**— координира превода, изпълнението, поточното предаване и обработката на грешки.
|
||||
|
||||
| File | Purpose |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. |
|
||||
| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. |
|
||||
| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. |
|
||||
| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. |
|
||||
|
||||
#### Request Lifecycle (chatCore.ts)
|
||||
| Файл | Цел |
|
||||
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` |**Централен оркестратор**(~600 реда). Обработва пълния жизнен цикъл на заявката: откриване на формат → превод → изпращане на изпълнител → стрийминг/не-стрийминг отговор → опресняване на токена → обработка на грешки → регистриране на използването. |
|
||||
| `responsesHandler.ts` | Адаптер за API за отговори на OpenAI: преобразува формата на отговорите → Завършвания на чат → изпраща до `chatCore` → конвертира SSE обратно във формат на отговорите. |
|
||||
| `embeddings.ts` | Манипулатор за генериране на вграждане: разрешава модел на вграждане → доставчик, изпраща до API на доставчика, връща съвместим с OpenAI отговор за вграждане. Поддържа 6+ доставчици. |
|
||||
| `imageGeneration.ts` | Манипулатор за генериране на изображения: разрешава модел на изображение → доставчик, поддържа режими, съвместими с OpenAI, Gemini-image (Антигравитация) и резервни (Nebius). Връща base64 или URL изображения. |#### Request Lifecycle (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -256,30 +244,28 @@ sequenceDiagram
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Services (`open-sse/services/`)
|
||||
|
||||
Business logic that supports the handlers and executors.
|
||||
|
||||
| File | Purpose |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
|
||||
| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
|
||||
| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). |
|
||||
| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
|
||||
| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
|
||||
| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
|
||||
| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
|
||||
| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
|
||||
| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
|
||||
| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
|
||||
| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
|
||||
| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
|
||||
| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
|
||||
| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |
|
||||
| Бизнес логика, която поддържа манипулаторите и изпълнителите. | File | Purpose |
|
||||
| ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
|
||||
| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
|
||||
| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). |
|
||||
| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
|
||||
| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
|
||||
| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
|
||||
| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
|
||||
| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
|
||||
| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
|
||||
| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
|
||||
| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
|
||||
| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
|
||||
| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
|
||||
| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |
|
||||
|
||||
#### Token Refresh Deduplication
|
||||
|
||||
@@ -348,9 +334,7 @@ flowchart LR
|
||||
|
||||
### 4.5 Translator (`open-sse/translator/`)
|
||||
|
||||
The **format translation engine** using a self-registering plugin system.
|
||||
|
||||
#### Архитектура
|
||||
**Машината за превод на формати**, използваща саморегистрираща се плъгин система.#### Архитектура
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
@@ -376,15 +360,13 @@ graph TD
|
||||
end
|
||||
```
|
||||
|
||||
| Directory | Files | Description |
|
||||
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. |
|
||||
| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. |
|
||||
| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. |
|
||||
| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
|
||||
#### Key Design: Self-Registering Plugins
|
||||
| Указател | Файлове | Описание |
|
||||
| ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| `заявка/` | 8 преводачи | Преобразувайте тела на заявки между формати. Всеки файл се саморегистрира чрез `register(from, to, fn)` при импортиране. |
|
||||
| `отговор/` | 7 преводачи | Преобразувайте поточно предавани отговори между формати. Обработва SSE типове събития, мисловни блокове, извиквания на инструменти. |
|
||||
| `помощници/` | 6 помощника | Споделени помощни програми: `claudeHelper` (извличане на системна подкана, конфигурация на мислене), `geminiHelper` (картографиране на части/съдържание), `openaiHelper` (филтриране на формат), `toolCallHelper` (генериране на ID, инжектиране на липсващ отговор), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Механизъм за превод: `translateRequest()`, `translateResponse()`, управление на състоянието, регистър. |
|
||||
| `formats.ts` | — | Константи на формата: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | #### Key Design: Self-Registering Plugins |
|
||||
|
||||
```javascript
|
||||
// Each translator file calls register() on import:
|
||||
@@ -399,17 +381,15 @@ import "./request/claude-to-openai.js"; // ← self-registers
|
||||
|
||||
### 4.6 Utils (`open-sse/utils/`)
|
||||
|
||||
| File | Purpose |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. |
|
||||
| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. |
|
||||
| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). |
|
||||
| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. |
|
||||
| `requestLogger.ts` | File-based request logging (opt-in via `ENABLE_REQUEST_LOGS=true`). Creates session folders with numbered files: `1_req_client.json` → `7_res_client.txt`. All I/O is async (fire-and-forget). Masks sensitive headers. |
|
||||
| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. |
|
||||
| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. |
|
||||
|
||||
#### SSE Streaming Pipeline
|
||||
| Файл | Цел |
|
||||
| ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
||||
| `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
|
||||
@@ -451,103 +431,81 @@ logs/
|
||||
|
||||
### 4.7 Application Layer (`src/`)
|
||||
|
||||
| Directory | Purpose |
|
||||
| ------------- | ---------------------------------------------------------------------- |
|
||||
| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers |
|
||||
| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared |
|
||||
| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic |
|
||||
| `src/models/` | Database model definitions |
|
||||
| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) |
|
||||
| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes |
|
||||
| `src/store/` | Application state management |
|
||||
| Указател | Цел |
|
||||
| ----------------- | ------------------------------------------------------------------------------------------------------------ | ----------------------- |
|
||||
| `src/приложение/` | Уеб потребителски интерфейс, API маршрути, Express междинен софтуер, манипулатори за обратно извикване OAuth |
|
||||
| `src/lib/` | Достъп до база данни (`localDb.ts`, `usageDb.ts`), удостоверяване, споделено |
|
||||
| `src/mitm/` | Прокси помощни програми Man-in-the-middle за прихващане на трафик на доставчик |
|
||||
| `src/модели/` | Дефиниции на модел на база данни |
|
||||
| `src/споделено/` | Обвивки около open-sse функции (доставчик, поток, грешка и др.) |
|
||||
| `src/sse/` | SSE манипулатори на крайни точки, които свързват библиотеката open-sse към експресни маршрути |
|
||||
| `src/магазин/` | Управление на състоянието на приложението | #### Notable API Routes |
|
||||
|
||||
#### Notable API Routes
|
||||
|
||||
| Route | Methods | Purpose |
|
||||
| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- |
|
||||
| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider |
|
||||
| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider |
|
||||
| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency |
|
||||
| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
|
||||
| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
|
||||
| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
|
||||
| `/api/sessions` | GET | Active session tracking and metrics |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
|
||||
---
|
||||
| Маршрут | Методи | Цел |
|
||||
| ---------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------- | --- |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | CRUD за потребителски модели на доставчик |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Обобщен каталог на всички модели (чат, вграждане, изображение, персонализирани), групирани по доставчик |
|
||||
| `/api/настройки/прокси` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Йерархична изходяща прокси конфигурация (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Валидира прокси свързаността и връща публичен IP/латентност |
|
||||
| `/v1/providers/[доставчик]/chat/completions` | ПУБЛИКАЦИЯ | Специализирани завършвания на чат за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[provider]/embeddings` | ПУБЛИКАЦИЯ | Специализирани вграждания за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[доставчик]/images/generations` | ПУБЛИКАЦИЯ | Специално генериране на изображения за всеки доставчик с валидиране на модел |
|
||||
| `/api/настройки/ip-филтър` | ВЗЕМИ/ПОСТАВИ | Управление на списък с разрешени/блокирани IP |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Конфигурация на бюджета на токена за разсъждение (преминаване/автоматично/персонализирано/адаптивно) |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Бързо инжектиране на глобална система за всички заявки |
|
||||
| `/api/сесии` | ВЗЕМЕТЕ | Проследяване на активна сесия и показатели |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка | --- |
|
||||
|
||||
## 5. Key Design Patterns
|
||||
|
||||
### 5.1 Hub-and-Spoke Translation
|
||||
|
||||
All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs.
|
||||
Всички формати се превеждат през**OpenAI формат като център**. Добавянето на нов доставчик изисква само писане на**една двойка**преводачи (към/от OpenAI), а не на N двойки.### 5.2 Executor Strategy Pattern
|
||||
|
||||
### 5.2 Executor Strategy Pattern
|
||||
Всеки доставчик има специален клас изпълнител, наследен от „BaseExecutor“. Фабриката в `executors/index.ts` избира правилния по време на изпълнение.### 5.3 Self-Registering Plugin System
|
||||
|
||||
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
|
||||
Модулите за транслатори се регистрират при импортиране чрез `register()`. Добавянето на нов преводач е просто създаване на файл и импортирането му.### 5.4 Account Fallback with Exponential Backoff
|
||||
|
||||
### 5.3 Self-Registering Plugin System
|
||||
Когато доставчикът върне 429/401/500, системата може да превключи към следващия акаунт, прилагайки експоненциално охлаждане (1s → 2s → 4s → max 2min).### 5.5 Combo Model Chains
|
||||
|
||||
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
|
||||
„Комбо“ групира множество низове „доставчик/модел“. Ако първият не успее, автоматично се върнете към следващия.### 5.6 Stateful Streaming Translation
|
||||
|
||||
### 5.4 Account Fallback with Exponential Backoff
|
||||
Преводът на отговор поддържа състоянието в SSE блокове (проследяване на мислещ блок, натрупване на извикване на инструмент, индексиране на блок съдържание) чрез механизма `initState()`.### 5.7 Usage Safety Buffer
|
||||
|
||||
When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
|
||||
|
||||
### 5.5 Combo Model Chains
|
||||
|
||||
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
|
||||
|
||||
### 5.6 Stateful Streaming Translation
|
||||
|
||||
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
|
||||
|
||||
### 5.7 Usage Safety Buffer
|
||||
|
||||
A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation.
|
||||
|
||||
---
|
||||
Добавя се буфер от 2000 токена към отчетеното използване, за да се предотврати достигането на ограниченията на контекстните прозорци на клиентите поради натоварване от системни подкани и превод на формати.---
|
||||
|
||||
## 6. Supported Formats
|
||||
|
||||
| Format | Direction | Identifier |
|
||||
| ----------------------- | --------------- | ------------------ |
|
||||
| OpenAI Chat Completions | source + target | `openai` |
|
||||
| OpenAI Responses API | source + target | `openai-responses` |
|
||||
| Anthropic Claude | source + target | `claude` |
|
||||
| Google Gemini | source + target | `gemini` |
|
||||
| Google Gemini CLI | target only | `gemini-cli` |
|
||||
| Antigravity | source + target | `antigravity` |
|
||||
| AWS Kiro | target only | `kiro` |
|
||||
| Cursor | target only | `cursor` |
|
||||
|
||||
---
|
||||
| Формат | Посока | Идентификатор |
|
||||
| ------------------------- | -------------- | ----------------- | --- |
|
||||
| Завършвания на OpenAI чат | източник + цел | `опенай` |
|
||||
| OpenAI Responses API | източник + цел | `openaj-отговори` |
|
||||
| Антропичен Клод | източник + цел | `клод` |
|
||||
| Google Gemini | източник + цел | `близнаци` |
|
||||
| Google Gemini CLI | само цел | `gemini-cli` |
|
||||
| Антигравитация | източник + цел | `антигравитация` |
|
||||
| AWS Киро | само цел | `киро` |
|
||||
| Курсор | само цел | `курсор` | --- |
|
||||
|
||||
## 7. Supported Providers
|
||||
|
||||
| Provider | Auth Method | Executor | Key Notes |
|
||||
| ------------------------ | ---------------------- | ----------- | --------------------------------------------- |
|
||||
| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header |
|
||||
| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint |
|
||||
| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing |
|
||||
| OpenAI | API key | Default | Standard Bearer auth |
|
||||
| Codex | OAuth | Codex | Injects system instructions, manages thinking |
|
||||
| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking |
|
||||
| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing |
|
||||
| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
|
||||
| Qwen | OAuth | Default | Standard auth |
|
||||
| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
|
||||
| OpenRouter | API key | Default | Standard Bearer auth |
|
||||
| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` |
|
||||
| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint |
|
||||
| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint |
|
||||
|
||||
---
|
||||
| Доставчик | Метод за удостоверяване | Изпълнител | Основни бележки |
|
||||
| ------------------------ | -------------------------------- | --------------- | -------------------------------------------------- | --- |
|
||||
| Антропичен Клод | 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 | По подразбиране | Стандартно удостоверяване |
|
||||
| Qoder | OAuth (основен + носител) | По подразбиране | Заглавка за двойно удостоверяване |
|
||||
| OpenRouter | API ключ | По подразбиране | Удостоверяване на стандартен носител |
|
||||
| GLM, Kimi, MiniMax | API ключ | По подразбиране | Съвместим с Claude, използвайте `x-api-key` |
|
||||
| `openai-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с OpenAI |
|
||||
| `anthropic-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с Claude | --- |
|
||||
|
||||
## 8. Data Flow Summary
|
||||
|
||||
|
||||
@@ -1,158 +1,132 @@
|
||||
# Test Coverage Plan (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [hi](../../hi/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md) · 🇹🇷 [tr](../../tr/docs/COVERAGE_PLAN.md)
|
||||
|
||||
---
|
||||
|
||||
Last updated: 2026-03-28
|
||||
Последна актуализация: 2026-03-28## Baseline
|
||||
|
||||
## Baseline
|
||||
Има няколко номера на покритие в зависимост от начина на изчисляване на отчета. За планиране само един от тях е полезен.
|
||||
|
||||
There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
|
||||
| Метрика | Обхват | Изявления / редове | Клонове | Функции | Бележки |
|
||||
| --------------------------- | ---------------------------------------------------------------------- | -----------------: | ------: | ------: | ---------------------------------------------------- |
|
||||
| Наследство | Стар `npm run test:coverage` | 79,42% | 75,15% | 67,94% | Надуто: брои тестовите файлове и изключва `open-sse` |
|
||||
| Диагностика | Само изходен код, с изключение на тестове и с изключение на `open-sse` | 68,16% | 63,55% | 64,06% | Полезно само за изолиране на `src/**` |
|
||||
| Препоръчителна базова линия | Само изходен код, с изключение на тестове и включително `open-sse` | 56,95% | 66,05% | 57,80% | Това е базовата линия за подобряване |
|
||||
|
||||
| Metric | Scope | Statements / Lines | Branches | Functions | Notes |
|
||||
| -------------------- | ----------------------------------------------------- | -----------------: | -------: | --------: | --------------------------------------------------- |
|
||||
| Legacy | Old `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Inflated: counts test files and excludes `open-sse` |
|
||||
| Diagnostic | Source-only, excluding tests and excluding `open-sse` | 68.16% | 63.55% | 64.06% | Useful only to isolate `src/**` |
|
||||
| Recommended baseline | Source-only, excluding tests and including `open-sse` | 56.95% | 66.05% | 57.80% | This is the project-wide baseline to improve |
|
||||
Препоръчителната базова линия е числото, спрямо което да се оптимизира.## Rules
|
||||
|
||||
The recommended baseline is the number to optimize against.
|
||||
|
||||
## Rules
|
||||
|
||||
- Coverage targets apply to source files, not to `tests/**`.
|
||||
- `open-sse/**` is part of the product and must remain in scope.
|
||||
- New code should not reduce coverage in touched areas.
|
||||
- Prefer testing behavior and branch outcomes over implementation details.
|
||||
- Prefer temp SQLite databases and small fixtures over broad mocks for `src/lib/db/**`.
|
||||
|
||||
## Current command set
|
||||
- Целите за покритие се отнасят за изходните файлове, а не за `tests/**`.
|
||||
- `open-sse/**` е част от продукта и трябва да остане в обхвата.
|
||||
- Новият код не трябва да намалява покритието в засегнатите области.
|
||||
- Предпочитайте поведението при тестване и резултатите от разклоненията пред подробностите за изпълнението.
|
||||
- Предпочитайте временни SQLite бази данни и малки модули пред широки макети за `src/lib/db/**`.## Current command set
|
||||
|
||||
- `npm run test:coverage`
|
||||
- Main source coverage gate for the unit test suite
|
||||
- Generates `text-summary`, `html`, `json-summary`, and `lcov`
|
||||
- Порта за покритие на главния източник за комплекта за тестване на единица
|
||||
- Генерира `text-summary`, `html`, `json-summary` и `lcov`
|
||||
- `npm run coverage:report`
|
||||
- Detailed file-by-file report from the latest run
|
||||
- `npm run test:coverage:legacy`
|
||||
- Historical comparison only
|
||||
- Подробен отчет файл по файл от последното изпълнение
|
||||
- `npm изпълнява тест: покритие: наследство`
|
||||
- Само историческо сравнение## Milestones
|
||||
|
||||
## Milestones
|
||||
| Фаза | Цел | Фокус |
|
||||
| ------ | ----------------------: | --------------------------------------------------------------- |
|
||||
| Фаза 1 | 60% извлечения / редове | Бързи печалби и покритие с нисък риск |
|
||||
| Фаза 2 | 65% извлечения / редове | БД и основи на трасе |
|
||||
| Фаза 3 | 70% извлечения / редове | Валидиране на доставчик и анализ на използването |
|
||||
| Фаза 4 | 75% извлечения / редове | `open-sse` преводачи и помощници |
|
||||
| Фаза 5 | 80% извлечения / редове | `open-sse` манипулатори и изпълнителни клонове |
|
||||
| Фаза 6 | 85% извлечения / редове | По-трудни крайни случаи, дълг на клонове, пакети за регресия |
|
||||
| Фаза 7 | 90% извлечения / редове | Окончателно почистване, затваряне на празнина, строга тресчотка |
|
||||
|
||||
| Phase | Target | Focus |
|
||||
| ------- | ---------------------: | ------------------------------------------------- |
|
||||
| Phase 1 | 60% statements / lines | Quick wins and low-risk utility coverage |
|
||||
| Phase 2 | 65% statements / lines | DB and route foundations |
|
||||
| Phase 3 | 70% statements / lines | Provider validation and usage analytics |
|
||||
| Phase 4 | 75% statements / lines | `open-sse` translators and helpers |
|
||||
| Phase 5 | 80% statements / lines | `open-sse` handlers and executor branches |
|
||||
| Phase 6 | 85% statements / lines | Harder edge cases, branch debt, regression suites |
|
||||
| Phase 7 | 90% statements / lines | Final sweep, gap closure, strict ratchet |
|
||||
Разклоненията и функциите трябва да растат нагоре с всяка фаза, но основната твърда цел са изявленията / редовете.## Priority hotspots
|
||||
|
||||
Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
|
||||
Тези файлове или области предлагат най-добра възвращаемост за следващите фази:
|
||||
|
||||
## Priority hotspots
|
||||
|
||||
These files or areas offer the best return for the next phases:
|
||||
|
||||
1. `open-sse/handlers`
|
||||
- `chatCore.ts` at 7.57%
|
||||
- Overall directory at 29.07%
|
||||
1. `open-sse/обработчици`
|
||||
- `chatCore.ts` на 7,57%
|
||||
- Обща директория на 29,07%
|
||||
2. `open-sse/translator/request`
|
||||
- Overall directory at 36.39%
|
||||
- Many translators are still near single-digit coverage
|
||||
- Обща директория на 36,39%
|
||||
- Много преводачи все още са близо до едноцифрено покритие
|
||||
3. `open-sse/translator/response`
|
||||
- Overall directory at 8.07%
|
||||
4. `open-sse/executors`
|
||||
- Overall directory at 36.62%
|
||||
- Обща директория на 8,07%
|
||||
4. `open-sse/изпълнители`
|
||||
- Обща директория на 36,62%
|
||||
5. `src/lib/db`
|
||||
- `models.ts` at 20.66%
|
||||
- `registeredKeys.ts` at 34.46%
|
||||
- `modelComboMappings.ts` at 36.25%
|
||||
- `settings.ts` at 46.40%
|
||||
- `webhooks.ts` at 33.33%
|
||||
- `models.ts` при 20,66%
|
||||
- `registeredKeys.ts` на 34,46%
|
||||
- `modelComboMappings.ts` на 36,25%
|
||||
- `settings.ts` на 46,40%
|
||||
- `webhooks.ts` на 33,33%
|
||||
6. `src/lib/usage`
|
||||
- `usageHistory.ts` at 21.12%
|
||||
- `usageStats.ts` at 9.56%
|
||||
- `costCalculator.ts` at 30.00%
|
||||
- `usageHistory.ts` при 21,12%
|
||||
- `usageStats.ts` при 9,56%
|
||||
- `costCalculator.ts` при 30,00%
|
||||
7. `src/lib/providers`
|
||||
- `validation.ts` at 41.16%
|
||||
8. Low-risk utility and API files for early gains
|
||||
- `validation.ts` при 41,16%
|
||||
8. Нискорискови помощни програми и API файлове за ранни печалби
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
|
||||
## Execution checklist
|
||||
- `src/app/api/providers/[id]/models/route.ts`## Execution checklist
|
||||
|
||||
### Phase 1: 56.95% -> 60%
|
||||
|
||||
- [x] Fix coverage metric so it reflects source code instead of test files
|
||||
- [x] Keep a legacy coverage script for comparison
|
||||
- [x] Record the baseline and hotspots in-repo
|
||||
- [ ] Add focused tests for low-risk utilities:
|
||||
- [x] Коригиране на показателя за покритие, така че да отразява изходния код вместо тестовите файлове
|
||||
- [x] Съхранявайте наследен скрипт за покритие за сравнение
|
||||
- [x] Запишете базовата линия и горещите точки в репо
|
||||
- [ ] Добавяне на фокусирани тестове за помощни програми с нисък риск:
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/fetchTimeout.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/display/names.ts`
|
||||
- [ ] Add route tests for:
|
||||
- [ ] Добавете тестове за маршрути за:
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`### Phase 2: 60% -> 65%
|
||||
|
||||
### Phase 2: 60% -> 65%
|
||||
|
||||
- [ ] Add DB-backed tests for:
|
||||
- [ ] Добавете тестове, поддържани от DB за:
|
||||
- `src/lib/db/modelComboMappings.ts`
|
||||
- `src/lib/db/settings.ts`
|
||||
- `src/lib/db/registeredKeys.ts`
|
||||
- [ ] Cover branch behavior in:
|
||||
- [ ] Покрийте поведението на клона в:
|
||||
- `src/lib/providers/validation.ts`
|
||||
- `src/app/api/v1/embeddings/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`### Phase 3: 65% -> 70%
|
||||
|
||||
### Phase 3: 65% -> 70%
|
||||
|
||||
- [ ] Add usage analytics tests for:
|
||||
- [ ] Добавете тестове за анализ на употребата за:
|
||||
- `src/lib/usage/usageHistory.ts`
|
||||
- `src/lib/usage/usageStats.ts`
|
||||
- `src/lib/usage/costCalculator.ts`
|
||||
- [ ] Expand route coverage for proxy management and settings branches
|
||||
- [ ] Разширете покритието на маршрута за клонове за управление на прокси и настройки### Phase 4: 70% -> 75%
|
||||
|
||||
### Phase 4: 70% -> 75%
|
||||
|
||||
- [ ] Cover translator helpers and central translation paths:
|
||||
- [ ] Покрийте помощните средства за преводачи и централните пътища за превод:
|
||||
- `open-sse/translator/index.ts`
|
||||
- `open-sse/translator/helpers/*`
|
||||
- `open-sse/translator/request/*`
|
||||
- `open-sse/translator/response/*`
|
||||
- `open-sse/translator/response/*`### Phase 5: 75% -> 80%
|
||||
|
||||
### Phase 5: 75% -> 80%
|
||||
|
||||
- [ ] Add handler-level tests for:
|
||||
- [ ] Добавете тестове на ниво манипулатор за:
|
||||
- `open-sse/handlers/chatCore.ts`
|
||||
- `open-sse/handlers/responsesHandler.js`
|
||||
- `open-sse/handlers/imageGeneration.js`
|
||||
- `open-sse/handlers/embeddings.js`
|
||||
- [ ] Add executor branch coverage for provider-specific auth, retries, and endpoint overrides
|
||||
- [ ] Добавете покритие на клона на изпълнителя за специфично за доставчика удостоверяване, повторни опити и замени на крайни точки### Phase 6: 80% -> 85%
|
||||
|
||||
### Phase 6: 80% -> 85%
|
||||
- [ ] Обединете повече комплекти крайни случаи в основния път на покритие
|
||||
- [ ] Увеличаване на функционалното покритие за DB модули със слабо покритие на конструктор/помощник
|
||||
- [ ] Запълване на пропуски в клонове в `settings.ts`, `registeredKeys.ts`, `validation.ts` и помощници на преводача### Phase 7: 85% -> 90%
|
||||
|
||||
- [ ] Merge more edge-case suites into the main coverage path
|
||||
- [ ] Increase function coverage for DB modules with weak constructor/helper coverage
|
||||
- [ ] Close branch gaps in `settings.ts`, `registeredKeys.ts`, `validation.ts`, and translator helpers
|
||||
- [ ] Третирайте останалите файлове с ниско покритие като блокери
|
||||
- [ ] Добавяне на регресионни тестове за всеки непокрит производствен бъг, коригиран по време на натискането до 90%
|
||||
- [ ] Повишете вратата на покритие в CI само след като локалната базова линия е стабилна за поне две последователни изпълнения## Ratchet policy
|
||||
|
||||
### Phase 7: 85% -> 90%
|
||||
Актуализирайте праговете за `npm run test:coverage` само след като проектът действително надхвърли следващия етап с удобен буфер.
|
||||
|
||||
- [ ] Treat the remaining low-coverage files as blockers
|
||||
- [ ] Add regression tests for every uncovered production bug fixed during the push to 90%
|
||||
- [ ] Raise the coverage gate in CI only after the local baseline is stable for at least two consecutive runs
|
||||
|
||||
## Ratchet policy
|
||||
|
||||
Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
|
||||
|
||||
Recommended ratchet sequence:
|
||||
Препоръчителна последователност на тресчотката:
|
||||
|
||||
1. 55/60/55
|
||||
2. 60/62/58
|
||||
@@ -163,8 +137,6 @@ Recommended ratchet sequence:
|
||||
7. 85/80/84
|
||||
8. 90/85/88
|
||||
|
||||
Order is `statements-lines / branches / functions`.
|
||||
Редът е `изявления-редове / разклонения / функции`.## Known gap
|
||||
|
||||
## Known gap
|
||||
|
||||
The current coverage command measures the main Node unit suite and includes source reached from it, including `open-sse`. It does not yet merge Vitest coverage into a single unified report. That merge is worth doing later, but it is not a blocker for starting the 60% -> 80% climb.
|
||||
Текущата команда за покритие измерва основния пакет от единици Node и включва източник, достигнат от него, включително „open-sse“. Все още не обединява покритието на Vitest в един общ отчет. Това сливане си струва да се направи по-късно, но не е блокер за започване на 60% -> 80% изкачване.
|
||||
|
||||
@@ -1,145 +1,105 @@
|
||||
# OmniRoute — Dashboard Features Gallery (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [hi](../../hi/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md) · 🇹🇷 [tr](../../tr/docs/FEATURES.md)
|
||||
|
||||
---
|
||||
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
---
|
||||
Визуално ръководство за всеки раздел на таблото за управление OmniRoute.---
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (Qoder, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

|
||||
Управлявайте връзките на доставчици на AI: OAuth доставчици (Claude Code, Codex, Gemini CLI), доставчици на API ключове (Groq, DeepSeek, OpenRouter) и безплатни доставчици (Qoder, Qwen, Kiro). Сметките в Kiro включват проследяване на кредитния баланс — оставащи кредити, обща надбавка и дата на подновяване, видими в Табло за управление → Използване.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Combos
|
||||
|
||||
Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
|
||||
|
||||

|
||||
Създавайте комбинации за маршрутизиране на модели с 6 стратегии: приоритетни, претеглени, кръгови, произволни, най-малко използвани и оптимизирани по отношение на разходите. Всяка комбинация свързва няколко модела с автоматичен резервен вариант и включва бързи шаблони и проверки за готовност.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Analytics
|
||||
|
||||
Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
|
||||
|
||||

|
||||
Изчерпателни анализи на използването с потребление на токени, оценки на разходите, топлинни карти на активността, седмични диаграми на разпределение и разбивки по доставчик.
|
||||
|
||||
---
|
||||
|
||||
## 🏥 System Health
|
||||
|
||||
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states.
|
||||
|
||||

|
||||
Мониторинг в реално време: време на работа, памет, версия, процентили на латентност (p50/p95/p99), статистика на кеша и състояния на прекъсвача на доставчика.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Translator Playground
|
||||
|
||||
Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream).
|
||||
|
||||

|
||||
Четири режима за отстраняване на грешки в API преводи:**Playground**(конвертор на формати),**Chat Tester**(заявки на живо),**Test Bench**(пакетни тестове) и**Live Monitor**(поток в реално време).
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Model Playground _(v2.0.9+)_
|
||||
|
||||
Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics.
|
||||
|
||||
---
|
||||
Тествайте всеки модел директно от таблото. Изберете доставчик, модел и крайна точка, пишете подкани с Monaco Editor, предавайте отговори в реално време, прекъсвайте по средата на потока и преглеждайте показатели за времето.---
|
||||
|
||||
## 🎨 Themes _(v2.0.5+)_
|
||||
|
||||
Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode.
|
||||
|
||||
---
|
||||
Цветови теми с възможност за персонализиране за цялото табло. Изберете от 7 предварително зададени цвята (корал, син, червен, зелен, виолетов, оранжев, циан) или създайте персонализирана тема, като изберете всеки шестнадесетичен цвят. Поддържа светъл, тъмен и системен режим.---
|
||||
|
||||
## ⚙️ Settings
|
||||
|
||||
Comprehensive settings panel with tabs:
|
||||
Изчерпателен панел с настройки с раздели:
|
||||
|
||||
- **General** — System storage, backup management (export/import database)
|
||||
- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning, auto-disable banned accounts, provider expiration monitoring
|
||||
- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode
|
||||
|
||||

|
||||
-**Общи**— Системно съхранение, управление на архивиране (база данни за експорт/импорт) -**Външен вид**— Селектор на тема (тъмно/светло/система), предварително зададени цветови теми и персонализирани цветове, видимост на журнала за здраве, контроли за видимост на елементи от страничната лента -**Сигурност**— API защита на крайната точка, персонализирано блокиране на доставчика, IP филтриране, информация за сесията -**Маршрутизиране**— Псевдоними на модела, влошаване на фоновата задача -**Устойчивост**— Устойчивост на лимита на скоростта, настройка на прекъсвача, автоматично деактивиране на забранени акаунти, наблюдение на изтичане на доставчика -**Разширени**— Замени на конфигурацията, одитна пътека на конфигурацията, резервен режим на влошаване
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI Tools
|
||||
|
||||
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping.
|
||||
|
||||

|
||||
Конфигурация с едно кликване за инструменти за кодиране на AI: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor и Factory Droid. Включва автоматизирано прилагане/нулиране на конфигурация, профили на свързване и картографиране на модела.
|
||||
|
||||
---
|
||||
|
||||
## 🤖 CLI Agents _(v2.0.11+)_
|
||||
|
||||
Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with:
|
||||
Табло за откриване и управление на CLI агенти. Показва мрежа от 14 вградени агента (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) с:
|
||||
|
||||
- **Installation status** — Installed / Not Found with version detection
|
||||
- **Protocol badges** — stdio, HTTP, etc.
|
||||
- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args)
|
||||
- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP
|
||||
|
||||
---
|
||||
-**Състояние на инсталацията**— Инсталирано / Не е намерено с откриване на версия -**Протоколни значки**— stdio, HTTP и др. -**Персонализирани агенти**— Регистрирайте всеки CLI инструмент чрез формуляр (име, двоичен файл, команда за версия, аргументи за генериране) -**CLI съпоставяне на пръстови отпечатъци**— Превключване за всеки доставчик, за да съответства на собствените подписи на CLI заявка, намалявайки риска от забрана, като същевременно запазва прокси IP---
|
||||
|
||||
## 🖼️ Media _(v2.0.3+)_
|
||||
|
||||
Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen.
|
||||
|
||||
---
|
||||
Генерирайте изображения, видеоклипове и музика от таблото за управление. Поддържа OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open и MusicGen.---
|
||||
|
||||
## 📝 Request Logs
|
||||
|
||||
Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details.
|
||||
|
||||

|
||||
Регистриране на заявки в реално време с филтриране по доставчик, модел, акаунт и API ключ. Показва кодове за състояние, използване на токени, латентност и подробности за отговора.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 API Endpoint
|
||||
|
||||
Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloudflare Quick Tunnel integration and cloud proxy support for remote access.
|
||||
|
||||

|
||||
Вашата унифицирана крайна точка на API с разбивка на възможностите: завършвания на чатове, API за отговори, вграждания, генериране на изображения, прекласиране, аудио транскрипция, текст към говор, модериране и регистрирани ключове за API. Интегриране на Cloudflare Quick Tunnel и поддръжка на облачен прокси за отдалечен достъп.
|
||||
|
||||
---
|
||||
|
||||
## 🔑 API Key Management
|
||||
|
||||
Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking.
|
||||
|
||||
---
|
||||
Създаване, обхват и отмяна на API ключове. Всеки ключ може да бъде ограничен до конкретни модели/доставчици с пълен достъп или разрешения само за четене. Визуално управление на ключове с проследяване на използването.---
|
||||
|
||||
## 📋 Audit Log
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
|
||||
---
|
||||
Проследяване на административни действия с филтриране по тип действие, актьор, цел, IP адрес и клеймо за време. Пълна история на събитията за сигурност.---
|
||||
|
||||
## 🖥️ Desktop Application
|
||||
|
||||
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, and one-click install.
|
||||
Настолно приложение Native Electron за Windows, macOS и Linux. Стартирайте OmniRoute като самостоятелно приложение с интеграция в системната област, офлайн поддръжка, автоматично актуализиране и инсталиране с едно щракване.
|
||||
|
||||
Key features:
|
||||
Ключови характеристики:
|
||||
|
||||
- Server readiness polling (no blank screen on cold start)
|
||||
- System tray with port management
|
||||
- Content Security Policy
|
||||
- Single-instance lock
|
||||
- Auto-update on restart
|
||||
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
|
||||
- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+)
|
||||
- Проучване на готовността на сървъра (без празен екран при студен старт)
|
||||
- Системна област с управление на портове
|
||||
- Политика за сигурност на съдържанието
|
||||
- Еднократно заключване
|
||||
- Автоматична актуализация при рестартиране
|
||||
- Платформено условен потребителски интерфейс (светофари на MacOS, заглавна лента по подразбиране на Windows/Linux)
|
||||
- Hardened Electron build packaging — символично свързаните `node_modules` в самостоятелния пакет се откриват и отхвърлят преди опаковането, предотвратявайки зависимостта по време на изпълнение от машината за изграждане (v2.5.5+)
|
||||
|
||||
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
|
||||
📖 Вижте [`electron/README.md`](../electron/README.md) за пълна документация.
|
||||
|
||||
380
docs/i18n/bg/docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
380
docs/i18n/bg/docs/FLY_IO_DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,380 @@
|
||||
# OmniRoute Fly.io 部署指南 (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/FLY_IO_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/FLY_IO_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
本文档记录 OmniRoute 在 Fly.io 上的实际部署方法,适用于两类场景:
|
||||
|
||||
- 首次把当前项目部署到 Fly.io
|
||||
- 后续代码更新后继续发布
|
||||
- 新项目参考同样流程部署
|
||||
|
||||
本文基于当前项目已经验证通过的配置整理,应用名为 `omniroute`。---
|
||||
|
||||
## 1. 部署目标
|
||||
|
||||
- 平台:Fly.io
|
||||
- 部署方式:本地 `flyctl` 直接发布
|
||||
- 运行方式:使用仓库内现有 `Dockerfile` 和 `fly.toml`
|
||||
- 数据持久化:Fly Volume 挂载到 `/data`
|
||||
- 访问地址:`https://omniroute.fly.dev/`---
|
||||
|
||||
## 2. 当前项目关键配置
|
||||
|
||||
当前仓库中的 `fly.toml` 已确认包含以下关键项:```toml
|
||||
app = 'omniroute'
|
||||
primary_region = 'sin'
|
||||
|
||||
[[mounts]]
|
||||
source = 'data'
|
||||
destination = '/data'
|
||||
|
||||
[processes]
|
||||
app = 'node run-standalone.mjs'
|
||||
|
||||
[http_service]
|
||||
internal_port = 20128
|
||||
|
||||
[env]
|
||||
TZ = "Asia/Shanghai"
|
||||
HOST = "0.0.0.0"
|
||||
HOSTNAME = "0.0.0.0"
|
||||
BIND = "0.0.0.0"
|
||||
|
||||
````
|
||||
|
||||
说明:
|
||||
|
||||
- `app = 'omniroute'` 决定实际部署到哪个 Fly 应用
|
||||
- `destination = '/data'` 决定持久卷挂载目录
|
||||
- 本项目必须让 `DATA_DIR=/data`,否则数据库和密钥会写到容器临时目录---
|
||||
|
||||
## 3. 必备工具
|
||||
|
||||
### 3.1 安装 Fly CLI
|
||||
|
||||
Windows PowerShell:```powershell
|
||||
pwsh -Command "iwr https://fly.io/install.ps1 -useb | iex"
|
||||
````
|
||||
|
||||
如果安装脚本在当前环境失败,也可以手动下载 `flyctl` 二进制并放到 `PATH` 中。### 3.2 登录 Fly 账号
|
||||
|
||||
```powershell
|
||||
flyctl auth login
|
||||
```
|
||||
|
||||
### 3.3 检查登录状态
|
||||
|
||||
```powershell
|
||||
flyctl auth whoami
|
||||
flyctl version
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 首次部署当前项目
|
||||
|
||||
### 4.1 获取代码并进入目录
|
||||
|
||||
```powershell
|
||||
git clone https://github.com/xiaoge1688/OmniRoute.git
|
||||
cd OmniRoute
|
||||
```
|
||||
|
||||
### 4.2 确认应用名
|
||||
|
||||
打开 `fly.toml`,重点看这一行:```toml
|
||||
app = 'omniroute'
|
||||
|
||||
````
|
||||
|
||||
如果你准备部署到自己的新应用,可改成全局唯一名称,例如:```toml
|
||||
app = 'omniroute-yourname'
|
||||
````
|
||||
|
||||
注意:
|
||||
|
||||
- 控制台里要看的是与 `fly.toml` 里 `app` 一致的应用
|
||||
- 以前如果用过别的名字,例如 `oroute`,不要和 `omniroute` 混淆### 4.3 创建应用
|
||||
|
||||
如果该应用尚不存在:```powershell
|
||||
flyctl apps create omniroute
|
||||
|
||||
````
|
||||
|
||||
如果你已经改成别的应用名,把 `omniroute` 替换成你的名字。### 4.4 首次部署
|
||||
|
||||
```powershell
|
||||
flyctl deploy
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## 5. 必配参数
|
||||
|
||||
本项目在 Fly.io 上建议至少配置以下参数。### 5.1 已验证使用的参数
|
||||
|
||||
这些参数已经在当前 `omniroute` 应用上实际部署:
|
||||
|
||||
- `API_KEY_SECRET`
|
||||
- `DATA_DIR`
|
||||
- `JWT_SECRET`
|
||||
- `МАШИНЕН_ИД_СОЛ`
|
||||
- `NEXT_PUBLIC_BASE_URL`
|
||||
- `STORAGE_ENCRYPTION_KEY`### 5.2 关于 `INITIAL_PASSWORD`
|
||||
|
||||
当前项目没有设置 `INITIAL_PASSWORD`,因为本次部署按需求不使用它。
|
||||
|
||||
如果不设置:
|
||||
|
||||
- 启动日志会提示默认密码是 `CHANGEME`
|
||||
- 部署后应尽快在系统设置中修改登录密码
|
||||
|
||||
如果你希望无人值守初始化后台密码,也可以后续补:
|
||||
|
||||
- `ПЪРВОНАЧАЛНА_ПАРОЛА`---
|
||||
|
||||
## 6. 推荐参数说明
|
||||
|
||||
### 6.1 Secrets 中设置
|
||||
|
||||
建议放入 Fly Secrets:
|
||||
|
||||
| 变量名 | 是否推荐 | 说明 |
|
||||
| ----------------------------- | -------- | ------------------------------ | ---------------------- |
|
||||
| `API_KEY_SECRET` | 必需 | API ключ 生成与校验使用 |
|
||||
| `JWT_SECRET` | 必需 | 登录态和 JWT 签名使用 |
|
||||
| `STORAGE_ENCRYPTION_KEY` | 强烈推荐 | 加密存储敏感连接信息 |
|
||||
| `ИДЕНТИФИКАТОР НА_МАШИНА_СОЛ` | 推荐 | 生成稳定机器标识 |
|
||||
| `ПЪРВОНАЧАЛНА_ПАРОЛА` | 可选 | 首次部署时直接指定后台初始密码 |
|
||||
| OAuth/API 私密凭证 | 按需 | 各类外部平台鉴权配置 | ### 6.2 当前项目推荐值 |
|
||||
|
||||
| 变量名 | 推荐值 |
|
||||
| ---------------------- | --------------------------- |
|
||||
| `DATA_DIR` | `/данни` |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `https://omniroute.fly.dev` |
|
||||
|
||||
说明:
|
||||
|
||||
- `DATA_DIR=/data` 非常关键,必须与 Fly Volume 挂载点一致
|
||||
- `NEXT_PUBLIC_BASE_URL` 用于调度器和前端回调等场景---
|
||||
|
||||
## 7. 一键设置参数
|
||||
|
||||
下面命令会生成安全随机值,并把当前项目需要的参数一次性写入 Fly Secrets。
|
||||
|
||||
说明:
|
||||
|
||||
- 不包含 `ПЪРВОНАЧАЛНА_ПАРОЛА`
|
||||
- 适用于当前项目 `omniroute````powershell
|
||||
$apiKeySecret = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$jwtSecret = [Convert]::ToHexString((1..64 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$machineIdSalt = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
$storageKey = [Convert]::ToHexString((1..32 | ForEach-Object { Get-Random -Minimum 0 -Maximum 256 })).ToLower()
|
||||
|
||||
flyctl secrets set ` API_KEY_SECRET=$apiKeySecret`
|
||||
JWT_SECRET=$jwtSecret `
|
||||
MACHINE_ID_SALT=$machineIdSalt ` STORAGE_ENCRYPTION_KEY=$storageKey`
|
||||
DATA_DIR=/data ` NEXT_PUBLIC_BASE_URL=https://omniroute.fly.dev`
|
||||
-a omniroute
|
||||
|
||||
````
|
||||
|
||||
如果你还要加初始密码:```powershell
|
||||
flyctl secrets set INITIAL_PASSWORD=你的强密码 -a omniroute
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## 8. 查看当前参数
|
||||
|
||||
```powershell
|
||||
flyctl secrets list -a omniroute
|
||||
```
|
||||
|
||||
如果控制台 `Тайни` 页面没有显示你期待的变量,先检查:
|
||||
|
||||
- 看的应用是不是 `omniroute`
|
||||
- `fly.toml` 的 `приложение` 是否和控制台应用一致---
|
||||
|
||||
## 9. 后续更新发布
|
||||
|
||||
代码有更新后,发布步骤很简单:```powershell
|
||||
git pull
|
||||
flyctl deploy
|
||||
|
||||
````
|
||||
|
||||
如果只更新参数,不改代码:```powershell
|
||||
flyctl secrets set KEY=value -a omniroute
|
||||
````
|
||||
|
||||
Fly 会自动滚动更新机器。### 9.1 跟踪原仓库更新并保留 fork 的 `fly.toml`
|
||||
|
||||
如果当前仓库是 fork,并且你要同步上游 `https://github.com/diegosouzapw/OmniRoute`的更新,推荐按下面流程执行。
|
||||
|
||||
先确认远程:```powershell
|
||||
git remote -v
|
||||
|
||||
````
|
||||
|
||||
应至少包含:
|
||||
|
||||
- `произход` 指向你自己的 разклонение
|
||||
- `нагоре по течението` 指向原仓库
|
||||
|
||||
如果没有 `нагоре`,先添加:```powershell
|
||||
git remote add upstream https://github.com/diegosouzapw/OmniRoute.git
|
||||
````
|
||||
|
||||
同步上游前,先抓取最新提交和标签:```powershell
|
||||
git fetch upstream --tags
|
||||
|
||||
````
|
||||
|
||||
查看当前版本和上游标签:```powershell
|
||||
git describe --tags --always
|
||||
git show --no-patch --oneline v3.4.7
|
||||
````
|
||||
|
||||
如果你想合并上游最新 `main`,并强制保留 fork 当前的 `fly.toml`,可按下面流程执行:```powershell
|
||||
git merge upstream/main
|
||||
git checkout HEAD~1 -- fly.toml
|
||||
git add -- fly.toml
|
||||
git commit -m "chore(deploy): keep fork fly.toml"
|
||||
git push origin main
|
||||
|
||||
````
|
||||
|
||||
说明:
|
||||
|
||||
- `git merge upstream/main` 用于同步原仓库最新代码
|
||||
- `git checkout HEAD~1 -- fly.toml` 用于恢复合并前你 fork 自己的 `fly.toml`
|
||||
- 如果上游没有改 `fly.toml`",这一步不会带来额外差异
|
||||
- 如果上游改了 `fly.toml`,这一步能确保 Fly 应用名、挂载卷、区域等 fork自定义部署配置不被覆盖
|
||||
|
||||
如果你明确只想对齐某个发布标签,例如 `v3.4.7`,也可以先确认标签是否已经包含在`нагоре/основен`:```powershell
|
||||
git merge-base --is-ancestor v3.4.7 upstream/main
|
||||
````
|
||||
|
||||
返回成功表示 `нагоре/основен` 已经包含该版本,直接合并 `нагоре/главен` 即可。### 9.2 同步上游后的标准发布顺序
|
||||
|
||||
同步原仓库完成后,推荐按下面顺序发布:
|
||||
|
||||
1. `git fetch upstream --tags`
|
||||
2. `git merge upstream/main`
|
||||
3. 恢复 вилица 的 `fly.toml`
|
||||
4. `git push origin main`
|
||||
5. `flyctl разгръщане`
|
||||
6. `flyctl status -a omniroute`
|
||||
7. `flyctl logs --no-tail -a omniroute`
|
||||
|
||||
这就是当前项目升级到 `v3.4.7` 时使用的实际流程。---
|
||||
|
||||
## 10. 发布后检查
|
||||
|
||||
### 10.1 查看应用状态
|
||||
|
||||
```powershell
|
||||
flyctl status -a omniroute
|
||||
```
|
||||
|
||||
### 10.2 查看启动日志
|
||||
|
||||
```powershell
|
||||
flyctl logs --no-tail -a omniroute
|
||||
```
|
||||
|
||||
### 10.3 检查网站可访问
|
||||
|
||||
```powershell
|
||||
try {
|
||||
(Invoke-WebRequest -Uri "https://omniroute.fly.dev" -MaximumRedirection 5 -UseBasicParsing).StatusCode
|
||||
} catch {
|
||||
if ($_.Exception.Response) {
|
||||
$_.Exception.Response.StatusCode.value__
|
||||
} else {
|
||||
throw
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
返回 `200` 说明站点已正常响应。---
|
||||
|
||||
## 11. 成功标志
|
||||
|
||||
部署成功后,日志里应看到类似内容:```text
|
||||
[bootstrap] Secrets persisted to: /data/server.env
|
||||
[DB] SQLite database ready: /data/storage.sqlite
|
||||
|
||||
````
|
||||
|
||||
这两个点很关键:
|
||||
|
||||
- `/data/server.env` 说明运行时密钥落到了持久卷
|
||||
- `/data/storage.sqlite` 说明数据库写入持久卷
|
||||
|
||||
如果你看到的是 `/app/data/...`,说明 `DATA_DIR` 没配对,需要立即修正。---
|
||||
|
||||
## 12. 常见问题
|
||||
|
||||
### 12.1 `Secrets` 页面是空的
|
||||
|
||||
通常有两种原因:
|
||||
|
||||
- 你还没执行 „набор тайни на flyctl“.
|
||||
- 你打开的是另一个应用,例如 `oroute`,不是 `omniroute`### 12.2 `flyctl deploy` 报 `app not found`
|
||||
|
||||
先创建应用:```powershell
|
||||
flyctl apps create omniroute
|
||||
````
|
||||
|
||||
### 12.3 `fly.toml` 解析失败
|
||||
|
||||
重点检查:
|
||||
|
||||
- 注释里是否有乱码字符
|
||||
- TOML 引号和缩进是否正确### 12.4 数据没有持久化
|
||||
|
||||
检查以下两点:
|
||||
|
||||
- `fly.toml` 中是否存在 `destination = '/data'`
|
||||
- `DATA_DIR` 是否设置为 `/data`### 12.5 不设置 `INITIAL_PASSWORD` 是否能跑
|
||||
|
||||
可以运行,但会回退到默认 `CHANGEME`。生产环境建议尽快修改后台密码。---
|
||||
|
||||
## 13. 新项目复用建议
|
||||
|
||||
如果以后是新项目照着这份文档部署,最少改这几项:
|
||||
|
||||
1. 修改 `fly.toml` 里的 `app`
|
||||
2. Изберете `NEXT_PUBLIC_BASE_URL`
|
||||
3. Изберете `DATA_DIR=/data`
|
||||
4. 重新生成 `API_KEY_SECRET`、`JWT_SECRET`、`MACHINE_ID_SALT`、`STORAGE_ENCRYPTION_KEY`
|
||||
5. 首次部署后检查日志是否写入 `/данни`
|
||||
|
||||
不要直接复用旧项目的密钥。---
|
||||
|
||||
## 14. 当前项目的最小发布清单
|
||||
|
||||
当前项目后续最常用的命令如下:```powershell
|
||||
flyctl auth whoami
|
||||
flyctl status -a omniroute
|
||||
flyctl secrets list -a omniroute
|
||||
flyctl deploy
|
||||
flyctl logs --no-tail -a omniroute
|
||||
|
||||
````
|
||||
|
||||
如果只是正常发版,核心就是:```powershell
|
||||
flyctl deploy
|
||||
````
|
||||
|
||||
如果是新环境首次部署R,核心就是:
|
||||
|
||||
1. „flyctl auth login“.
|
||||
2. `flyctl apps create omniroute`
|
||||
3. `flyctl secrets set ... -a omniroute`
|
||||
4. `flyctl разгръщане`
|
||||
5. `flyctl logs --no-tail -a omniroute`
|
||||
397
docs/i18n/bg/docs/I18N.md
Normal file
397
docs/i18n/bg/docs/I18N.md
Normal file
@@ -0,0 +1,397 @@
|
||||
# i18n — Internationalization Guide (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/I18N.md) · 🇪🇸 [es](../../es/docs/I18N.md) · 🇫🇷 [fr](../../fr/docs/I18N.md) · 🇩🇪 [de](../../de/docs/I18N.md) · 🇮🇹 [it](../../it/docs/I18N.md) · 🇷🇺 [ru](../../ru/docs/I18N.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/I18N.md) · 🇯🇵 [ja](../../ja/docs/I18N.md) · 🇰🇷 [ko](../../ko/docs/I18N.md) · 🇸🇦 [ar](../../ar/docs/I18N.md) · 🇮🇳 [hi](../../hi/docs/I18N.md) · 🇮🇳 [in](../../in/docs/I18N.md) · 🇹🇭 [th](../../th/docs/I18N.md) · 🇻🇳 [vi](../../vi/docs/I18N.md) · 🇮🇩 [id](../../id/docs/I18N.md) · 🇲🇾 [ms](../../ms/docs/I18N.md) · 🇳🇱 [nl](../../nl/docs/I18N.md) · 🇵🇱 [pl](../../pl/docs/I18N.md) · 🇸🇪 [sv](../../sv/docs/I18N.md) · 🇳🇴 [no](../../no/docs/I18N.md) · 🇩🇰 [da](../../da/docs/I18N.md) · 🇫🇮 [fi](../../fi/docs/I18N.md) · 🇵🇹 [pt](../../pt/docs/I18N.md) · 🇷🇴 [ro](../../ro/docs/I18N.md) · 🇭🇺 [hu](../../hu/docs/I18N.md) · 🇧🇬 [bg](../../bg/docs/I18N.md) · 🇸🇰 [sk](../../sk/docs/I18N.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/I18N.md) · 🇮🇱 [he](../../he/docs/I18N.md) · 🇵🇭 [phi](../../phi/docs/I18N.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/I18N.md) · 🇨🇿 [cs](../../cs/docs/I18N.md) · 🇹🇷 [tr](../../tr/docs/I18N.md)
|
||||
|
||||
---
|
||||
|
||||
OmniRoute поддържа**30 езика**с пълен превод на потребителския интерфейс на таблото, преведена документация и RTL поддръжка за арабски и иврит.## Quick Reference
|
||||
|
||||
| Задача | Команда |
|
||||
| -------------------------- | ---------------------------------------------------------------------------------------- | -------------- |
|
||||
| Генериране на преводи | `нодови скриптове/i18n/generate-multilang.mjs съобщения` |
|
||||
| Превод на документи (LLM) | `python3 scripts/i18n_autotranslate.py --api-url <url> --api-key <ключ> --model <модел>` |
|
||||
| Валидиране на локал | `python3 скриптове/validate_translation.py quick -l cs` |
|
||||
| Проверете кодовите ключове | `python3 скриптове/check_translations.py` |
|
||||
| Генериране на QA доклад | `node scripts/i18n/generate-qa-checklist.mjs` |
|
||||
| Visual QA (Playwright) | `скриптове на възел/i18n/run-visual-qa.mjs` | ## Архитектура |
|
||||
|
||||
### Source of Truth
|
||||
|
||||
-**UI низове**: `src/i18n/messages/en.json` (английски източник, ~2800 ключа) -**Локални файлове**: `src/i18n/messages/{locale}.json` (30 превода) -**Framework**: `next-intl` с разделителна способност на базата на бисквитки -**Конфигурация**: `src/i18n/config.ts` — дефинира всичките 30 локализации, имена на езици, флагове### Runtime Flow
|
||||
|
||||
1. Потребителят избира език → набор от бисквитки `NEXT_LOCALE`
|
||||
2. `src/i18n/request.ts` разрешава локал: бисквитка → заглавка `Accept-Language` → резервен `en`
|
||||
3. Динамичното импортиране зарежда `messages/{locale}.json`
|
||||
4. Компонентите използват `useTranslations("namespace")` и `t("key")`### Supported Locales
|
||||
|
||||
| Код | Език | RTL | Код на Google Преводач |
|
||||
| --------- | ---------------------- | --- | ---------------------- | ------------------------ |
|
||||
| `ar` | العربية | Да | `ar` |
|
||||
| `bg` | Български | Не | `bg` |
|
||||
| `cs` | Чещина | Не | `cs` |
|
||||
| `да` | Dansk | Не | `да` |
|
||||
| `de` | Deutsch | Не | `de` |
|
||||
| `es` | Español | Не | `es` |
|
||||
| `fi` | Suomi | Не | `fi` |
|
||||
| `fr` | Français | Не | `fr` |
|
||||
| `той` | עברית | Да | `iw` |
|
||||
| `здравей` | हिन्दी | Не | `здравей` |
|
||||
| `ху` | маджарски | Не | `ху` |
|
||||
| `id` | Bahasa Indonesia | Не | `id` |
|
||||
| `то` | италиански | Не | `то` |
|
||||
| `ja` | 日本語 | Не | `ja` |
|
||||
| `ко` | 한국어 | Не | `ко` |
|
||||
| `ms` | Bahasa Melayu | Не | `ms` |
|
||||
| `nl` | Холандия | Не | `nl` |
|
||||
| `не` | Norsk | Не | `не` |
|
||||
| `фи` | филипински | Не | `tl` |
|
||||
| `pl` | Полски | Не | `pl` |
|
||||
| `pt` | Português (Португалия) | Не | `pt` |
|
||||
| `pt-BR` | Português (Бразилия) | Не | `pt` |
|
||||
| `ro` | Română | Не | `ro` |
|
||||
| `ru` | Русский | Не | `ru` |
|
||||
| `sk` | Slovenčina | Не | `sk` |
|
||||
| `sv` | Свенска | Не | `sv` |
|
||||
| `th` | ไทย | Не | `th` |
|
||||
| `tr` | турски | Не | `tr` |
|
||||
| `uk-UA` | украински | Не | `uk` |
|
||||
| „vi“ | Tiếng Việt | Не | „vi“ |
|
||||
| `zh-CN` | 中文 (简体) | Не | `zh-CN` | ## Adding a New Language |
|
||||
|
||||
### 1. Register the Locale
|
||||
|
||||
Редактирайте `src/i18n/config.ts`:```ts
|
||||
// Add to LOCALES array
|
||||
"xx",
|
||||
// Add to LANGUAGES array
|
||||
{ code: "xx", label: "XX", name: "Language Name", flag: "🏳️" },
|
||||
|
||||
````
|
||||
|
||||
### 2. Add to Generator
|
||||
|
||||
Редактирайте `scripts/i18n/generate-multilang.mjs` — добавете запис към `LOCALE_SPECS`:```js
|
||||
{
|
||||
code: "xx",
|
||||
googleTl: "xx",
|
||||
label: "XX",
|
||||
flag: "🏳️",
|
||||
languageName: "Language Name",
|
||||
readmeName: "Language Name",
|
||||
docsName: "Language Name",
|
||||
},
|
||||
````
|
||||
|
||||
### 3. Generate Initial Translation
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs messages
|
||||
```
|
||||
|
||||
Това създава `src/i18n/messages/xx.json`, автоматично преведено от `en.json` чрез Google Translate.### 4. Review & Fix Auto-Translations
|
||||
|
||||
Автоматичните преводи са отправна точка. Прегледайте ръчно за:
|
||||
|
||||
- Техническа точност
|
||||
- Терминология, подходяща за контекста
|
||||
- Правилно боравене с контейнери (`{count}`, `{value}` и т.н.)### 5. Validate
|
||||
|
||||
```bash
|
||||
python3 scripts/validate_translation.py quick -l xx
|
||||
python3 scripts/validate_translation.py diff common -l xx
|
||||
```
|
||||
|
||||
### 6. Generate Translated Documentation
|
||||
|
||||
```bash
|
||||
node scripts/i18n/generate-multilang.mjs docs
|
||||
```
|
||||
|
||||
## Auto-Translation Pipeline
|
||||
|
||||
### generate-multilang.mjs (Google Translate)
|
||||
|
||||
**Основна машина за автоматичен превод**— използва безплатен API на Google Преводач за генериране на преводи за UI низове, README и документация.```bash
|
||||
node scripts/i18n/generate-multilang.mjs [messages|readme|docs|all]
|
||||
|
||||
````
|
||||
|
||||
| Режим | Какво прави |
|
||||
| ---------- | ---------------------------------------------------------------------------- |
|
||||
| `съобщения` | Превежда липсващите ключове в `src/i18n/messages/{locale}.json` от `en.json` |
|
||||
| `прочете ме` | Превежда `README.md` във всички локали като `README.{code}.md` в корена на проекта |
|
||||
| `документи` | Превежда `DOC_SOURCE_FILES` в `docs/i18n/{locale}/{docName}` |
|
||||
| `всички` | Работи и в трите режима |
|
||||
|
||||
**Характеристики:**
|
||||
|
||||
-**Текстова защита**: Маскира кодови блокове (` ``` `), вграден код (`` ` ``), маркдаун връзки/изображения (`[text](url)`), HTML тагове, таблици и контейнери за ICU (`{count}`, `{value}`, `{total}` и др.) преди превод, след което ги възстановява
|
||||
-**Чункирано пакетиране**: Съединява множество низове с разделители `__OMNIROUTE_I18N_SEPARATOR__` за минимизиране на извикванията на API (максимум 1800 символа на заявка)
|
||||
-**Кеш в паметта**: Избягва излишни извиквания на API за повтарящи се низове в рамките на сесия
|
||||
-**Логика на повторен опит**: Експоненциално забавяне (до 5 опита с 300ms × забавяне на опита) за 429/5xx грешки
|
||||
-**Изчакване**: 20 секунди на заявка
|
||||
-**Пропускане на съществуващ**: Ако целевият файл вече съществува, той НЕ се презаписва
|
||||
|
||||
**Важни поведения:**
|
||||
|
||||
- `docs/i18n/README.md` се**регенерира**при всяко изпълнение — това е автоматично генериран индекс на всички документи
|
||||
- Основните `README.{code}.md` файлове се създават само ако не съществуват (пропуска локалите в `EXISTING_README_CODES`)
|
||||
- Езиковите ленти (`🌐**Езици:**...`) се вмъкват/актуализират автоматично във всички преведени документи### i18n_autotranslate.py (LLM-based)
|
||||
|
||||
**Вторичен преводач**— използва всеки OpenAI-съвместим LLM API (включително самия OmniRoute) за превод на съществуващи `docs/i18n/` маркдаун файлове. Най-доброто за изглаждане или повторен превод на документи с по-добро качество от Google Translate.```bash
|
||||
python3 scripts/i18n_autotranslate.py \
|
||||
--api-url http://localhost:20128/v1 \
|
||||
--api-key sk-your-key \
|
||||
--model gpt-4o
|
||||
````
|
||||
|
||||
**Характеристики:**
|
||||
|
||||
- Сканира `docs/i18n/` файлове за маркиране за английски параграфи
|
||||
- Пропуска кодови блокове, таблици и вече преведено съдържание
|
||||
- Изпраща параграфи до LLM с подкана на системата за технически превод
|
||||
- Поддържа всички 30 езика## Validation & QA
|
||||
|
||||
### validate_translation.py
|
||||
|
||||
**Инструмент за валидиране на преводи**— сравнява всеки локал JSON с `en.json` и докладва за проблеми.```bash
|
||||
|
||||
# Quick check (counts only)
|
||||
|
||||
python3 scripts/validate_translation.py quick -l cs
|
||||
|
||||
# Output:
|
||||
|
||||
# Missing: 0
|
||||
|
||||
# Untranslated: 0
|
||||
|
||||
# Ignored (UNTRANSLATABLE_KEYS): 236
|
||||
|
||||
# Detailed diff by category
|
||||
|
||||
python3 scripts/validate_translation.py diff common -l cs
|
||||
python3 scripts/validate_translation.py diff settings -l cs
|
||||
|
||||
# Export to CSV
|
||||
|
||||
python3 scripts/validate_translation.py csv -l cs > report.csv
|
||||
|
||||
# Export to Markdown
|
||||
|
||||
python3 scripts/validate_translation.py md -l cs > report.md
|
||||
|
||||
# Full report (default)
|
||||
|
||||
python3 scripts/validate_translation.py -l cs
|
||||
|
||||
````
|
||||
|
||||
**Открива:**
|
||||
|
||||
-**Липсващи ключове**— ключове в `en.json`, но не и в локалния файл
|
||||
-**Допълнителни ключове**— ключове в локалния файл, но не и в `en.json`
|
||||
-**Непреведени ключове**— ключове, където стойността на локала е равна на английския източник (с изключение на списъка с разрешени)
|
||||
-**Несъответствия на контейнери**— контейнери на ICU, които не съвпадат между източника и превода
|
||||
|
||||
**Кодове за изход:**
|
||||
| Код | Значение |
|
||||
|------|---------|
|
||||
| 0 | ОК |
|
||||
| 1 | Обща грешка |
|
||||
| 2 | Липсващи низове (твърда грешка) |
|
||||
| 3 | Непреведено предупреждение (меко) |
|
||||
|
||||
**Среда:**Задайте `TRANSLATION_LANG=cs` или използвайте флаг `-l cs`.### check_translations.py
|
||||
|
||||
**Проверка на ключове от код към JSON**— сканира `src/**/*.tsx` и `src/**/*.ts` за извиквания на `useTranslations()` и проверява, че всички посочени ключове съществуват в `en.json`.```bash
|
||||
# Basic check
|
||||
python3 scripts/check_translations.py
|
||||
|
||||
# Verbose output
|
||||
python3 scripts/check_translations.py --verbose
|
||||
|
||||
# Auto-fix (adds missing keys to en.json)
|
||||
python3 scripts/check_translations.py --fix
|
||||
````
|
||||
|
||||
### generate-qa-checklist.mjs
|
||||
|
||||
**QA за статичен анализ**— сканира файловете на страницата Next.js за показатели на риска i18n и генерира отчет за Markdown.```bash
|
||||
node scripts/i18n/generate-qa-checklist.mjs
|
||||
|
||||
````
|
||||
|
||||
**Чекове:**
|
||||
|
||||
- Използване на клас с фиксирана ширина (риск от препълване)
|
||||
- Насочени ляво/дясно класове (RTL риск)
|
||||
- Склонни към изрязване модели
|
||||
- Локален паритет (липсващи/допълнителни ключове срещу `en.json`)
|
||||
- Ленти за избор на език README в приоритетни локали (`es`, `fr`, `de`, `ja`, `ar`)
|
||||
|
||||
**Изход:**`docs/reports/i18n-qa-checklist-{date}.md`### run-visual-qa.mjs
|
||||
|
||||
**Визуална проверка на качеството чрез Playwright**— прави екранни снимки на всички маршрути на таблото за управление в множество локали и прозорци за изглед, след което оценява изправността на страницата.```bash
|
||||
# Default: es, fr, de, ja, ar on localhost:20128
|
||||
node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom base URL and locales
|
||||
QA_BASE_URL=http://staging.example.com QA_LOCALES=de,fr node scripts/i18n/run-visual-qa.mjs
|
||||
|
||||
# Custom routes
|
||||
QA_ROUTES=/dashboard/settings,/dashboard/providers node scripts/i18n/run-visual-qa.mjs
|
||||
````
|
||||
|
||||
**Открива:**
|
||||
|
||||
- Преливане на текст
|
||||
- Изрязване на елементи
|
||||
- Несъответствия в RTL оформлението
|
||||
|
||||
**Изход:**`docs/reports/i18n-visual-qa-{date}.md` + JSON отчет## Managing Untranslatable Keys
|
||||
|
||||
### untranslatable-keys.json
|
||||
|
||||
**Файл:**`scripts/i18n/untranslatable-keys.json`
|
||||
|
||||
Списък с разрешени ключове, които трябва да останат идентични с английския източник. Използва се от `validate_translation.py` за избягване на фалшиво положителни "непреведени" предупреждения.```json
|
||||
{
|
||||
"description": "Keys that should remain untranslated...",
|
||||
"keys": [
|
||||
"common.model",
|
||||
"common.oauth",
|
||||
"health.cpu",
|
||||
...
|
||||
]
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
**Какво принадлежи тук:**
|
||||
|
||||
- Имена на марки/продукти: `landing.brandName`, `common.social-github`
|
||||
- Технически термини/акроними: `health.cpu`, `mcpDashboard.pid`, `settings.ai`
|
||||
- низове за ICU/формат: `apiManager.modelsCount`, `health.millisecondsShort`
|
||||
- Стойности на контейнери: `providers.openaiBaseUrlPlaceholder`, `cliTools.baseUrlPlaceholder`
|
||||
- Имена на протоколи: `common.http`, `common.oauth`, `providers.oauth2Label`
|
||||
- Секции за навигация: `sidebar.primarySection`, `sidebar.cliSection`
|
||||
|
||||
**За да добавите ключ:**Редактирайте масива `keys` в `scripts/i18n/untranslatable-keys.json` и изпълнете отново проверката.## CI Integration
|
||||
|
||||
### GitHub Actions (`.github/workflows/ci.yml`)
|
||||
|
||||
CI тръбопроводът валидира всички локали при всяко натискане и PR:
|
||||
|
||||
1.**`i18n-matrix` задание**— динамично открива всички локални файлове (с изключение на `en.json`)
|
||||
2.**`i18n` job**— изпълнява `validate_translation.py quick -l '<lang>'` за всеки локал паралелно
|
||||
3.**`ci-summary` задание**— обобщава резултатите в обобщение на таблото```yaml
|
||||
# i18n-matrix: discovers languages
|
||||
LANGS=$(ls src/i18n/messages/*.json | xargs -n1 basename | sed 's/.json$//' | grep -v '^en$')
|
||||
|
||||
# i18n: validates each language
|
||||
python3 scripts/validate_translation.py quick -l '${{ matrix.lang }}'
|
||||
````
|
||||
|
||||
**Изход на таблото:**```
|
||||
|
||||
## 🌍 Translations
|
||||
|
||||
| Metric | Value |
|
||||
| ------------------ | ----- |
|
||||
| Languages checked | 30 |
|
||||
| Total untranslated | 0 |
|
||||
|
||||
✅ All translations complete
|
||||
|
||||
```
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
|
||||
src/i18n/
|
||||
├── config.ts # Locale definitions (30 locales, RTL config)
|
||||
├── request.ts # Runtime locale resolution
|
||||
└── messages/
|
||||
├── en.json # Source of truth (~2800 keys)
|
||||
├── cs.json # Czech translation
|
||||
├── de.json # German translation
|
||||
└── ... # 30 locale files total
|
||||
|
||||
scripts/
|
||||
├── i18n/
|
||||
│ ├── generate-multilang.mjs # Auto-translation engine (Google Translate, 888 lines)
|
||||
│ ├── generate-qa-checklist.mjs # Static analysis QA
|
||||
│ ├── run-visual-qa.mjs # Playwright visual QA
|
||||
│ └── untranslatable-keys.json # Allowlist for validation (236 keys)
|
||||
├── validate_translation.py # Translation validator
|
||||
├── check_translations.py # Code-to-JSON key checker
|
||||
└── i18n_autotranslate.py # LLM-based doc translator
|
||||
|
||||
.github/workflows/
|
||||
└── ci.yml # i18n validation in CI matrix
|
||||
|
||||
docs/
|
||||
├── I18N.md # This file — i18n toolchain documentation
|
||||
├── i18n/
|
||||
│ ├── README.md # Auto-generated language index
|
||||
│ ├── cs/ # Czech docs
|
||||
│ │ └── docs/
|
||||
│ │ ├── I18N.md # Czech translation of this file
|
||||
│ │ └── ...
|
||||
│ ├── de/ # German docs
|
||||
│ └── ... # 30 locale directories
|
||||
└── reports/
|
||||
├── i18n-qa-checklist-_.md # Static analysis reports
|
||||
└── i18n-visual-qa-_.md # Visual QA reports
|
||||
|
||||
````
|
||||
|
||||
## Best Practices
|
||||
|
||||
### When Editing Translations
|
||||
|
||||
1.**Винаги първо редактирайте `en.json`**— това е източникът на истината
|
||||
2.**Изпълнете `generate-multilang.mjs messages`**, за да разпространявате нови ключове към всички локали
|
||||
3.**Преглед на автоматичните преводи**— Google Translate е отправна точка, а не крайна
|
||||
4.**Потвърдете преди ангажиране**— `python3 scripts/validate_translation.py quick -l <lang>`
|
||||
5.**Актуализирайте `untranslatable-keys.json`**, ако даден ключ трябва да остане на английски### Placeholder Safety
|
||||
|
||||
- Заместителите на ICU (`{count}`, `{value}`, `{total}`, `{seconds}`) трябва да бъдат запазени точно
|
||||
- Форматите за множествено число (`{count, plural, one {# model} other {# models}}`) трябва да поддържат структура
|
||||
- Валидаторът автоматично открива несъответствията на контейнерите### Adding New Translation Keys in Code
|
||||
|
||||
```tsx
|
||||
// Use namespaced keys
|
||||
const t = useTranslations("settings");
|
||||
t("cacheSettings"); // maps to settings.cacheSettings in JSON
|
||||
|
||||
// Run check_translations.py to verify keys exist
|
||||
python3 scripts/check_translations.py --verbose
|
||||
````
|
||||
|
||||
### RTL Considerations
|
||||
|
||||
- Арабски (`ar`) и иврит (`he`) са RTL локали
|
||||
- Избягвайте твърдо кодиран `left`/`right` CSS — използвайте `start`/`end` логически свойства
|
||||
- Visual QA улавя несъответствията на RTL оформлението чрез `run-visual-qa.mjs`## Known Issues & History
|
||||
|
||||
### `in.json` → `hi.json` Fix
|
||||
|
||||
Генераторът първоначално използва `code: "in"` (отхвърлен код на Google Translate) за хинди вместо правилния ISO 639-1 `hi`. Това създаде осиротяло `in.json` дубликат на `hi.json`. Коригирано чрез промяна на `code: "in"` на `code: "hi"` в `generate-multilang.mjs` и премахване на осиротелия файл.### `docs/i18n/README.md` Is Auto-Generated
|
||||
|
||||
Файлът `docs/i18n/README.md` е напълно регенериран от `generate-multilang.mjs docs`. Всички ръчни редакции ще бъдат загубени. Използвайте `docs/I18N.md` (този файл) за ръкописна документация, която трябва да остане.### External Untranslatable Keys List
|
||||
|
||||
Списъкът с разрешени `untranslatable-keys.json` беше преместен от вграден набор на Python в `validate_translation.py` към външен JSON файл за по-лесна поддръжка. Валидаторът го зарежда по време на изпълнение.### `generate-multilang.mjs` Hindi Code Fix
|
||||
|
||||
Генераторът първоначално използва `code: "in"` (отхвърлен код на Google Translate) за хинди вместо правилния ISO 639-1 `hi`. Това беше въведено в комит нагоре по веригата `952b0b22c` от `diegosouzapw`. Поправено чрез промяна на `code: "in"` на `code: "hi"` в масива `LOCALE_SPECS` и премахване на осиротелия `in.json` файл.### `validate_translation.py` Ignored Count Output
|
||||
|
||||
„Бързата“ проверка вече показва броя на игнорираните ключове от „untranslatable-keys.json“:```
|
||||
Missing: 0
|
||||
Untranslated: 0
|
||||
Ignored (UNTRANSLATABLE_KEYS): 236
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
@@ -1,87 +1,72 @@
|
||||
# OmniRoute MCP Server Documentation (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/MCP-SERVER.md) · 🇪🇸 [es](../../es/docs/MCP-SERVER.md) · 🇫🇷 [fr](../../fr/docs/MCP-SERVER.md) · 🇩🇪 [de](../../de/docs/MCP-SERVER.md) · 🇮🇹 [it](../../it/docs/MCP-SERVER.md) · 🇷🇺 [ru](../../ru/docs/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/MCP-SERVER.md) · 🇯🇵 [ja](../../ja/docs/MCP-SERVER.md) · 🇰🇷 [ko](../../ko/docs/MCP-SERVER.md) · 🇸🇦 [ar](../../ar/docs/MCP-SERVER.md) · 🇮🇳 [in](../../in/docs/MCP-SERVER.md) · 🇹🇭 [th](../../th/docs/MCP-SERVER.md) · 🇻🇳 [vi](../../vi/docs/MCP-SERVER.md) · 🇮🇩 [id](../../id/docs/MCP-SERVER.md) · 🇲🇾 [ms](../../ms/docs/MCP-SERVER.md) · 🇳🇱 [nl](../../nl/docs/MCP-SERVER.md) · 🇵🇱 [pl](../../pl/docs/MCP-SERVER.md) · 🇸🇪 [sv](../../sv/docs/MCP-SERVER.md) · 🇳🇴 [no](../../no/docs/MCP-SERVER.md) · 🇩🇰 [da](../../da/docs/MCP-SERVER.md) · 🇫🇮 [fi](../../fi/docs/MCP-SERVER.md) · 🇵🇹 [pt](../../pt/docs/MCP-SERVER.md) · 🇷🇴 [ro](../../ro/docs/MCP-SERVER.md) · 🇭🇺 [hu](../../hu/docs/MCP-SERVER.md) · 🇧🇬 [bg](../../bg/docs/MCP-SERVER.md) · 🇸🇰 [sk](../../sk/docs/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/MCP-SERVER.md) · 🇮🇱 [he](../../he/docs/MCP-SERVER.md) · 🇵🇭 [phi](../../phi/docs/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/MCP-SERVER.md) · 🇨🇿 [cs](../../cs/docs/MCP-SERVER.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/MCP-SERVER.md) · 🇪🇸 [es](../../es/docs/MCP-SERVER.md) · 🇫🇷 [fr](../../fr/docs/MCP-SERVER.md) · 🇩🇪 [de](../../de/docs/MCP-SERVER.md) · 🇮🇹 [it](../../it/docs/MCP-SERVER.md) · 🇷🇺 [ru](../../ru/docs/MCP-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/MCP-SERVER.md) · 🇯🇵 [ja](../../ja/docs/MCP-SERVER.md) · 🇰🇷 [ko](../../ko/docs/MCP-SERVER.md) · 🇸🇦 [ar](../../ar/docs/MCP-SERVER.md) · 🇮🇳 [hi](../../hi/docs/MCP-SERVER.md) · 🇮🇳 [in](../../in/docs/MCP-SERVER.md) · 🇹🇭 [th](../../th/docs/MCP-SERVER.md) · 🇻🇳 [vi](../../vi/docs/MCP-SERVER.md) · 🇮🇩 [id](../../id/docs/MCP-SERVER.md) · 🇲🇾 [ms](../../ms/docs/MCP-SERVER.md) · 🇳🇱 [nl](../../nl/docs/MCP-SERVER.md) · 🇵🇱 [pl](../../pl/docs/MCP-SERVER.md) · 🇸🇪 [sv](../../sv/docs/MCP-SERVER.md) · 🇳🇴 [no](../../no/docs/MCP-SERVER.md) · 🇩🇰 [da](../../da/docs/MCP-SERVER.md) · 🇫🇮 [fi](../../fi/docs/MCP-SERVER.md) · 🇵🇹 [pt](../../pt/docs/MCP-SERVER.md) · 🇷🇴 [ro](../../ro/docs/MCP-SERVER.md) · 🇭🇺 [hu](../../hu/docs/MCP-SERVER.md) · 🇧🇬 [bg](../../bg/docs/MCP-SERVER.md) · 🇸🇰 [sk](../../sk/docs/MCP-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/MCP-SERVER.md) · 🇮🇱 [he](../../he/docs/MCP-SERVER.md) · 🇵🇭 [phi](../../phi/docs/MCP-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/MCP-SERVER.md) · 🇨🇿 [cs](../../cs/docs/MCP-SERVER.md) · 🇹🇷 [tr](../../tr/docs/MCP-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
> Model Context Protocol server with 16 intelligent tools
|
||||
> Модел на Context Protocol сървър с 16 интелигентни инструмента## Инсталиране
|
||||
|
||||
## Инсталиране
|
||||
OmniRoute MCP е вграден. Започнете го с:`bash
|
||||
omniroute --mcp`
|
||||
|
||||
OmniRoute MCP is built-in. Start it with:
|
||||
Или чрез отворения транспорт:```bash
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Or via the open-sse transport:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
|
||||
```
|
||||
|
||||
## IDE Configuration
|
||||
|
||||
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
|
||||
Вижте [IDE Configs](integrations/ide-configs.md) за настройка на Antigravity, Cursor, Copilot и Claude Desktop.---## Essential Tools (8)
|
||||
|
||||
---
|
||||
|
||||
## Essential Tools (8)
|
||||
|
||||
| Tool | Description |
|
||||
| Инструмент | Описание |
|
||||
| :------------------------------ | :--------------------------------------- |
|
||||
| `omniroute_get_health` | Gateway health, circuit breakers, uptime |
|
||||
| `omniroute_list_combos` | All configured combos with models |
|
||||
| `omniroute_get_combo_metrics` | Performance metrics for a specific combo |
|
||||
| `omniroute_switch_combo` | Switch active combo by ID/name |
|
||||
| `omniroute_check_quota` | Quota status per provider or all |
|
||||
| `omniroute_route_request` | Send a chat completion through OmniRoute |
|
||||
| `omniroute_cost_report` | Cost analytics for a time period |
|
||||
| `omniroute_list_models_catalog` | Full model catalog with capabilities |
|
||||
| `omniroute_get_health` | Здраве на шлюза, прекъсвачи, време за работа |
|
||||
| `omniroute_list_combos` | Всички конфигурирани комбинации с модели |
|
||||
| `omniroute_get_combo_metrics` | Показатели за ефективност за конкретна комбинация |
|
||||
| `omniroute_switch_combo` | Превключете активното комбо по ID/име |
|
||||
| `omniroute_check_quota` | Състояние на квотата за доставчик или всички |
|
||||
| `omniroute_route_request` | Изпратете завършване на чат чрез OmniRoute |
|
||||
| `omniroute_cost_report` | Анализ на разходите за период от време |
|
||||
| `omniroute_list_models_catalog` | Пълен каталог на модели с възможности |## Advanced Tools (8)
|
||||
|
||||
## Advanced Tools (8)
|
||||
| Инструмент | Описание |
|
||||
| :-------------------------------- | :---------------------------------------------------------- |
|
||||
| `omniroute_simulate_route` | Симулация на сухо движение с резервно дърво |
|
||||
| `omniroute_set_budget_guard` | Бюджет на сесията с действие за влошаване/блокиране/предупреждение |
|
||||
| `omniroute_set_resilience_profile` | Прилагане на консервативна/балансирана/агресивна предварителна настройка |
|
||||
| `omniroute_test_combo` | Тествайте на живо всички модели в комбо чрез реална заявка нагоре |
|
||||
| `omniroute_get_provider_metrics` | Подробни показатели за един доставчик |
|
||||
| `omniroute_best_combo_for_task` | Препоръка за годност на задачите с алтернативи |
|
||||
| `omniroute_explain_route` | Обяснете минало решение за маршрутизиране |
|
||||
| `omniroute_get_session_snapshot` | Пълно състояние на сесията: разходи, токени, грешки |## Удостоверяване
|
||||
|
||||
| Tool | Description |
|
||||
| :--------------------------------- | :---------------------------------------------------------- |
|
||||
| `omniroute_simulate_route` | Dry-run routing simulation with fallback tree |
|
||||
| `omniroute_set_budget_guard` | Session budget with degrade/block/alert actions |
|
||||
| `omniroute_set_resilience_profile` | Apply conservative/balanced/aggressive preset |
|
||||
| `omniroute_test_combo` | Live-test all models in a combo via a real upstream request |
|
||||
| `omniroute_get_provider_metrics` | Detailed metrics for one provider |
|
||||
| `omniroute_best_combo_for_task` | Task-fitness recommendation with alternatives |
|
||||
| `omniroute_explain_route` | Explain a past routing decision |
|
||||
| `omniroute_get_session_snapshot` | Full session state: costs, tokens, errors |
|
||||
MCP инструментите се удостоверяват чрез API ключови обхвати. Всеки инструмент изисква специфични обхвати:
|
||||
|
||||
## Authentication
|
||||
| Обхват | Инструменти |
|
||||
| :------------- | :---------------------------------------------------- |
|
||||
| `read:здраве` | get_health, get_provider_metrics |
|
||||
| `read:combos` | list_combos, get_combo_metrics |
|
||||
| `write:combos` | switch_combo |
|
||||
| `четене:квота` | проверка_квота |
|
||||
| `write:route` | route_request, simulate_route, test_combo |
|
||||
| `read:usage` | cost_report, get_session_snapshot, explain_route |
|
||||
| `write:config` | set_budget_guard, set_resilience_profile |
|
||||
| `read:models` | list_modeli_katalog, най-добра_комбо_за_задача |## Регистриране на одит
|
||||
|
||||
MCP tools are authenticated via API key scopes. Each tool requires specific scopes:
|
||||
Всяко извикване на инструмента се регистрира в `mcp_tool_audit` с:
|
||||
|
||||
| Scope | Tools |
|
||||
| :------------- | :----------------------------------------------- |
|
||||
| `read:health` | get_health, get_provider_metrics |
|
||||
| `read:combos` | list_combos, get_combo_metrics |
|
||||
| `write:combos` | switch_combo |
|
||||
| `read:quota` | check_quota |
|
||||
| `write:route` | route_request, simulate_route, test_combo |
|
||||
| `read:usage` | cost_report, get_session_snapshot, explain_route |
|
||||
| `write:config` | set_budget_guard, set_resilience_profile |
|
||||
| `read:models` | list_models_catalog, best_combo_for_task |
|
||||
- Име на инструмента, аргументи, резултат
|
||||
- Продължителност (ms), успех/неуспех
|
||||
- API ключ хеш, времево клеймо## Файлове
|
||||
|
||||
## Audit Logging
|
||||
|
||||
Every tool call is logged to `mcp_tool_audit` with:
|
||||
|
||||
- Tool name, arguments, result
|
||||
- Duration (ms), success/failure
|
||||
- API key hash, timestamp
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| :------------------------------------------- | :------------------------------------------ |
|
||||
| `open-sse/mcp-server/server.ts` | MCP server creation + 16 tool registrations |
|
||||
| `open-sse/mcp-server/transport.ts` | Stdio + HTTP transport |
|
||||
| `open-sse/mcp-server/auth.ts` | API key + scope validation |
|
||||
| `open-sse/mcp-server/audit.ts` | Tool call audit logging |
|
||||
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 advanced tool handlers |
|
||||
| Файл | Цел |
|
||||
| :------------------------------------------ | :------------------------------------------ |
|
||||
| `open-sse/mcp-server/server.ts` | Създаване на MCP сървър + 16 инструмента за регистрация |
|
||||
| `open-sse/mcp-server/transport.ts` | Stdio + HTTP транспорт |
|
||||
| `open-sse/mcp-server/auth.ts` | API ключ + валидиране на обхват |
|
||||
| `open-sse/mcp-server/audit.ts` | Регистриране на одита на обажданията на инструмента |
|
||||
| `open-sse/mcp-server/tools/advancedTools.ts` | 8 усъвършенствани манипулатори на инструменти |
|
||||
```
|
||||
|
||||
@@ -1,37 +1,26 @@
|
||||
# Release Checklist (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../es/docs/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../fr/docs/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../de/docs/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../it/docs/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../ru/docs/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../ja/docs/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../ko/docs/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../ar/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../../in/docs/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../th/docs/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../vi/docs/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../id/docs/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../ms/docs/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../nl/docs/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../pl/docs/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../sv/docs/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../no/docs/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../da/docs/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../fi/docs/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../pt/docs/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../ro/docs/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../hu/docs/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../bg/docs/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../sk/docs/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../he/docs/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../phi/docs/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../cs/docs/RELEASE_CHECKLIST.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../../es/docs/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../../fr/docs/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../../de/docs/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../../it/docs/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../../ru/docs/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../../ja/docs/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../../ko/docs/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../../ar/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [hi](../../hi/docs/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../../in/docs/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../../th/docs/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../../vi/docs/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../../id/docs/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../../ms/docs/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../../nl/docs/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../../pl/docs/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../../sv/docs/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../../no/docs/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../../da/docs/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../../fi/docs/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../../pt/docs/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../../ro/docs/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../../hu/docs/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../../bg/docs/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../../sk/docs/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../../he/docs/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../../phi/docs/RELEASE_CHECKLIST.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/RELEASE_CHECKLIST.md) · 🇨🇿 [cs](../../cs/docs/RELEASE_CHECKLIST.md) · 🇹🇷 [tr](../../tr/docs/RELEASE_CHECKLIST.md)
|
||||
|
||||
---
|
||||
|
||||
Use this checklist before tagging or publishing a new OmniRoute release.
|
||||
Използвайте този контролиран списък, преди да маркирате или публикувате нова версия на OmniRoute.## Version and Changelog
|
||||
|
||||
## Version and Changelog
|
||||
1. Премахнете версията на `package.json` (`x.y.z`) в клона за освобождаване.
|
||||
2. Преместете бележките по изданието от `## [Unreleased]` в `CHANGELOG.md` в раздел с данни:
|
||||
- `## [x.y.z] — ГГГГ-ММ-ДД`
|
||||
3. Запазете `## [Unreleased]` като първа секция на регистъра, за да промените за предстояща работа.
|
||||
4. Уверете се, че последният раздел на semver в `CHANGELOG.md` е равен на версията `package.json`.## API Docs
|
||||
|
||||
1. Bump `package.json` version (`x.y.z`) in the release branch.
|
||||
2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
|
||||
- `## [x.y.z] — YYYY-MM-DD`
|
||||
3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
|
||||
4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
|
||||
5. Актуализирайте `docs/openapi.yaml`:
|
||||
- `info.version` трябва да е равно на `package.json` версия.
|
||||
6. Валидирайте примери за крайната точка, ако договорите за API са променени.## Runtime Docs
|
||||
|
||||
## API Docs
|
||||
7. Прегледайте `docs/ARCHITECTURE.md` за дрейф за съхранение/изпълнение.
|
||||
8. Прегледайте `docs/TROUBLESHOOTING.md` за env var и оперативен drift.
|
||||
9. Актуализирайте локализираните документи, ако изходните документи са се променили значително.## Automated Check
|
||||
|
||||
1. Update `docs/openapi.yaml`:
|
||||
- `info.version` must equal `package.json` version.
|
||||
2. Validate endpoint examples if API contracts changed.
|
||||
Стартирайте защитата на синхронизирането локално, преди да отворите PR:`bash
|
||||
npm стартирайте проверка:docs-sync`
|
||||
|
||||
## Runtime Docs
|
||||
|
||||
1. Review `docs/ARCHITECTURE.md` for storage/runtime drift.
|
||||
2. Review `docs/TROUBLESHOOTING.md` for env var and operational drift.
|
||||
3. Update localized docs if source docs changed significantly.
|
||||
|
||||
## Automated Check
|
||||
|
||||
Run the sync guard locally before opening PR:
|
||||
|
||||
```bash
|
||||
npm run check:docs-sync
|
||||
```
|
||||
|
||||
CI also runs this check in `.github/workflows/ci.yml` (lint job).
|
||||
CI също изпълнява тази проверка в `.github/workflows/ci.yml` (задание за мъх).
|
||||
|
||||
@@ -1,95 +1,68 @@
|
||||
# Troubleshooting (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/TROUBLESHOOTING.md) · 🇪🇸 [es](../../es/docs/TROUBLESHOOTING.md) · 🇫🇷 [fr](../../fr/docs/TROUBLESHOOTING.md) · 🇩🇪 [de](../../de/docs/TROUBLESHOOTING.md) · 🇮🇹 [it](../../it/docs/TROUBLESHOOTING.md) · 🇷🇺 [ru](../../ru/docs/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/TROUBLESHOOTING.md) · 🇯🇵 [ja](../../ja/docs/TROUBLESHOOTING.md) · 🇰🇷 [ko](../../ko/docs/TROUBLESHOOTING.md) · 🇸🇦 [ar](../../ar/docs/TROUBLESHOOTING.md) · 🇮🇳 [in](../../in/docs/TROUBLESHOOTING.md) · 🇹🇭 [th](../../th/docs/TROUBLESHOOTING.md) · 🇻🇳 [vi](../../vi/docs/TROUBLESHOOTING.md) · 🇮🇩 [id](../../id/docs/TROUBLESHOOTING.md) · 🇲🇾 [ms](../../ms/docs/TROUBLESHOOTING.md) · 🇳🇱 [nl](../../nl/docs/TROUBLESHOOTING.md) · 🇵🇱 [pl](../../pl/docs/TROUBLESHOOTING.md) · 🇸🇪 [sv](../../sv/docs/TROUBLESHOOTING.md) · 🇳🇴 [no](../../no/docs/TROUBLESHOOTING.md) · 🇩🇰 [da](../../da/docs/TROUBLESHOOTING.md) · 🇫🇮 [fi](../../fi/docs/TROUBLESHOOTING.md) · 🇵🇹 [pt](../../pt/docs/TROUBLESHOOTING.md) · 🇷🇴 [ro](../../ro/docs/TROUBLESHOOTING.md) · 🇭🇺 [hu](../../hu/docs/TROUBLESHOOTING.md) · 🇧🇬 [bg](../../bg/docs/TROUBLESHOOTING.md) · 🇸🇰 [sk](../../sk/docs/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/TROUBLESHOOTING.md) · 🇮🇱 [he](../../he/docs/TROUBLESHOOTING.md) · 🇵🇭 [phi](../../phi/docs/TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/TROUBLESHOOTING.md) · 🇨🇿 [cs](../../cs/docs/TROUBLESHOOTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/TROUBLESHOOTING.md) · 🇪🇸 [es](../../es/docs/TROUBLESHOOTING.md) · 🇫🇷 [fr](../../fr/docs/TROUBLESHOOTING.md) · 🇩🇪 [de](../../de/docs/TROUBLESHOOTING.md) · 🇮🇹 [it](../../it/docs/TROUBLESHOOTING.md) · 🇷🇺 [ru](../../ru/docs/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/TROUBLESHOOTING.md) · 🇯🇵 [ja](../../ja/docs/TROUBLESHOOTING.md) · 🇰🇷 [ko](../../ko/docs/TROUBLESHOOTING.md) · 🇸🇦 [ar](../../ar/docs/TROUBLESHOOTING.md) · 🇮🇳 [hi](../../hi/docs/TROUBLESHOOTING.md) · 🇮🇳 [in](../../in/docs/TROUBLESHOOTING.md) · 🇹🇭 [th](../../th/docs/TROUBLESHOOTING.md) · 🇻🇳 [vi](../../vi/docs/TROUBLESHOOTING.md) · 🇮🇩 [id](../../id/docs/TROUBLESHOOTING.md) · 🇲🇾 [ms](../../ms/docs/TROUBLESHOOTING.md) · 🇳🇱 [nl](../../nl/docs/TROUBLESHOOTING.md) · 🇵🇱 [pl](../../pl/docs/TROUBLESHOOTING.md) · 🇸🇪 [sv](../../sv/docs/TROUBLESHOOTING.md) · 🇳🇴 [no](../../no/docs/TROUBLESHOOTING.md) · 🇩🇰 [da](../../da/docs/TROUBLESHOOTING.md) · 🇫🇮 [fi](../../fi/docs/TROUBLESHOOTING.md) · 🇵🇹 [pt](../../pt/docs/TROUBLESHOOTING.md) · 🇷🇴 [ro](../../ro/docs/TROUBLESHOOTING.md) · 🇭🇺 [hu](../../hu/docs/TROUBLESHOOTING.md) · 🇧🇬 [bg](../../bg/docs/TROUBLESHOOTING.md) · 🇸🇰 [sk](../../sk/docs/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/TROUBLESHOOTING.md) · 🇮🇱 [he](../../he/docs/TROUBLESHOOTING.md) · 🇵🇭 [phi](../../phi/docs/TROUBLESHOOTING.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/TROUBLESHOOTING.md) · 🇨🇿 [cs](../../cs/docs/TROUBLESHOOTING.md) · 🇹🇷 [tr](../../tr/docs/TROUBLESHOOTING.md)
|
||||
|
||||
---
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
Често срещани проблеми и решения за OmniRoute.---## Quick Fixes
|
||||
|
||||
---
|
||||
|
||||
## Quick Fixes
|
||||
|
||||
| Problem | Solution |
|
||||
| ----------------------------- | ------------------------------------------------------------------ |
|
||||
| First login not working | Set `INITIAL_PASSWORD` in `.env` (no hardcoded default) |
|
||||
| Dashboard opens on wrong port | Set `PORT=20128` and `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| No 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) |
|
||||
|
||||
---
|
||||
|
||||
## Provider Issues
|
||||
| Проблем | Решение |
|
||||
| ----------------------------------------------- | ------------------------------------------------------------------------------ | --------------------- |
|
||||
| Първото влизане не работи | Задайте `INITIAL_PASSWORD` в `.env` (без твърдо кодирано подразбиране) |
|
||||
| Таблото се отваря на грешен порт | Задайте `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 схема за постоянство на настройките) | ---## Provider Issues |
|
||||
|
||||
### "Language model did not provide messages"
|
||||
|
||||
**Cause:** Provider quota exhausted.
|
||||
**Причина:**Квотата на доставчика е изчерпана.
|
||||
|
||||
**Fix:**
|
||||
**Коригиране:**
|
||||
|
||||
1. Check dashboard quota tracker
|
||||
2. Use a combo with fallback tiers
|
||||
3. Switch to cheaper/free tier
|
||||
1. Проверете инструмента за проследяване на квотите на таблото за управление
|
||||
2. Използвайте комбо с резервни нива
|
||||
3. Преминете към по-евтино/безплатно ниво### Rate Limiting
|
||||
|
||||
### Rate Limiting
|
||||
**Причина:**Абонаментната квота е изчерпана.
|
||||
|
||||
**Cause:** Subscription quota exhausted.
|
||||
**Коригиране:**
|
||||
|
||||
**Fix:**
|
||||
- Добавете резервен вариант: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Използвайте GLM/MiniMax като евтино резервно копие### OAuth Token Expired
|
||||
|
||||
- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Use GLM/MiniMax as cheap backup
|
||||
OmniRoute автоматично опреснява токените. Ако проблемите продължават:
|
||||
|
||||
### OAuth Token Expired
|
||||
|
||||
OmniRoute auto-refreshes tokens. If issues persist:
|
||||
|
||||
1. Dashboard → Provider → Reconnect
|
||||
2. Delete and re-add the provider connection
|
||||
|
||||
---
|
||||
|
||||
## Cloud Issues
|
||||
1. Табло → Доставчик → Свързване отново
|
||||
2. Изтрийте и добавете отново връзката с доставчика---## Cloud Issues
|
||||
|
||||
### Cloud Sync Errors
|
||||
|
||||
1. Verify `BASE_URL` points to your running instance (e.g., `http://localhost:20128`)
|
||||
2. Verify `CLOUD_URL` points to your cloud endpoint (e.g., `https://omniroute.dev`)
|
||||
3. Keep `NEXT_PUBLIC_*` values aligned with server-side values
|
||||
1. Проверете дали `BASE_URL` е към вашия работен екземпляр (напр. `http://localhost:20128`)
|
||||
2. Проверете дали `CLOUD_URL` е към вашата крайна точка в облака (напр. `https://omniroute.dev`)
|
||||
3. Поддържайте стойността `NEXT_PUBLIC_*` в съответствие със стойността от страната на сървъра### Cloud `stream=false` Връща 500
|
||||
|
||||
### Cloud `stream=false` Returns 500
|
||||
**Симптом:**`Неочакван токен 'd'...` в крайната точка на облака за повикане без точно предаване.
|
||||
|
||||
**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
|
||||
**Причина:**Upstream връща SSE полезен продукт, докато клиентът очаква JSON.
|
||||
|
||||
**Cause:** Upstream returns SSE payload while client expects JSON.
|
||||
**Заобиколно решение:**Използвайте `stream=true` за директни повикания в облака. Локалното време за изпълнение включва резервен SSE→JSON.### Cloud Says Connected but "Invalid API key"
|
||||
|
||||
**Workaround:** Use `stream=true` for cloud direct calls. Local runtime includes SSE→JSON fallback.
|
||||
|
||||
### Cloud Says Connected but "Invalid API key"
|
||||
|
||||
1. Create a fresh key from local dashboard (`/api/keys`)
|
||||
2. Run cloud sync: Enable Cloud → Sync Now
|
||||
3. Old/non-synced keys can still return `401` on cloud
|
||||
|
||||
---
|
||||
|
||||
## Docker Issues
|
||||
1. Създайте нов ключ от локалното табло за управление (`/api/keys`)
|
||||
2. Стартирайте облачна синхронизация: Активирайте облака → Синхронизирай сега
|
||||
3. Старите/несинхронизираните ключове все още могат да връщат „401“ в облака---## Docker Issues
|
||||
|
||||
### CLI Tool Shows Not Installed
|
||||
|
||||
1. Check runtime fields: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. For portable mode: use image target `runner-cli` (bundled CLIs)
|
||||
3. For host mount mode: set `CLI_EXTRA_PATHS` and mount host bin directory as read-only
|
||||
4. If `installed=true` and `runnable=false`: binary was found but failed healthcheck
|
||||
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`: двоичният файл е намерен, но проверката на състоянието е неуспешна### Quick Runtime Validation```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
|
||||
### Quick Runtime Validation
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/claude-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -97,160 +70,108 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
|
||||
|
||||
### High Costs
|
||||
|
||||
1. Check usage stats in Dashboard → Usage
|
||||
2. Switch primary model to GLM/MiniMax
|
||||
3. Use free tier (Gemini CLI, Qoder) for non-critical tasks
|
||||
4. Set cost budgets per API key: Dashboard → API Keys → Budget
|
||||
|
||||
---
|
||||
|
||||
## Debugging
|
||||
1. Проверете статистическите данни за употреба в Табло → Използване
|
||||
2. Превключете основния модел на GLM/MiniMax
|
||||
3. Използвайте безплатно ниво (Gemini CLI, Qoder) за некритични задачи
|
||||
4. Задайте бюджети за разходи за API ключ: Табло за управление → API ключове → Бюджет---## Debugging
|
||||
|
||||
### Enable Request Logs
|
||||
|
||||
Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory.
|
||||
|
||||
### Check Provider Health
|
||||
|
||||
```bash
|
||||
Задайте `ENABLE_REQUEST_LOGS=true` във вашия `.env` файл. Дневниците се появяват в директорията `logs/`.### Проверете здравето на доставчика```bash
|
||||
# Health dashboard
|
||||
http://localhost:20128/dashboard/health
|
||||
|
||||
# API health check
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
````
|
||||
|
||||
### Runtime Storage
|
||||
|
||||
- Main state: `${DATA_DIR}/storage.sqlite` (providers, combos, aliases, keys, settings)
|
||||
- Usage: SQLite tables in `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + optional `${DATA_DIR}/log.txt` and `${DATA_DIR}/call_logs/`
|
||||
- Request logs: `<repo>/logs/...` (when `ENABLE_REQUEST_LOGS=true`)
|
||||
|
||||
---
|
||||
|
||||
## Circuit Breaker Issues
|
||||
- Основно състояние: `${DATA_DIR}/storage.sqlite` (доставчици, комбинации, псевдоними, ключове, настройки)
|
||||
- Използване: SQLite таблици в `storage.sqlite` (`usage_history`, `call_logs`, `proxy_logs`) + незадължително `${DATA_DIR}/log.txt` и `${DATA_DIR}/call_logs/`
|
||||
- Заявки за регистрационни файлове: `<repo>/logs/...` (като `ENABLE_REQUEST_LOGS=true`)---## Circuit Breaker Issues
|
||||
|
||||
### Provider stuck in OPEN state
|
||||
|
||||
When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
|
||||
При прекъсване на веригата на доставчика е ОТВОРЕЕН, заявките се блокират, докато изтече времето за охлаждане.
|
||||
|
||||
**Fix:**
|
||||
**Коригиране:**
|
||||
|
||||
1. Go to **Dashboard → Settings → Resilience**
|
||||
2. Check the circuit breaker card for the affected provider
|
||||
3. Click **Reset All** to clear all breakers, or wait for the cooldown to expire
|
||||
4. Verify the provider is actually available before resetting
|
||||
1. Отидете на**Табло → Настройки → Устойчивост**
|
||||
2. Проверете картата на прекъсвача на сървъра на доставчика
|
||||
3. Щракнете върху**Нулиране на всички**, за да изчистите всички прекъсвачи, или изчакайте времето за охлаждане да изтече
|
||||
4. Уверете се, че доставчикът действително е наличен, преди да нулира### Доставчикът продължава да изключва прекъсвача
|
||||
|
||||
### Provider keeps tripping the circuit breaker
|
||||
Ако доставчикът многократно влезе в ОТВОРЕНО състояние:
|
||||
|
||||
If a provider repeatedly enters OPEN state:
|
||||
|
||||
1. Check **Dashboard → Health → Provider Health** for the failure pattern
|
||||
2. Go to **Settings → Resilience → Provider Profiles** and increase the failure threshold
|
||||
3. Check if the provider has changed API limits or requires re-authentication
|
||||
4. Review latency telemetry — high latency may cause timeout-based failures
|
||||
|
||||
---
|
||||
|
||||
## Audio Transcription Issues
|
||||
1. Проверете**Таблото → Здраве → Здраве на доставчика**за модел на повреда
|
||||
2. Отидете на**Настройки → Устойчивост → Профили на доставчици**и увеличите прага на отказ
|
||||
3. Проверете дали доставчикът е променил ограниченията на API или изисква повторно удостоверяване
|
||||
4. Прегледайте телеметрията за латентност — високата латентност може да причини грешки, базирани на изчакване---## Audio Transcription Issues
|
||||
|
||||
### "Unsupported model" error
|
||||
|
||||
- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
|
||||
- Verify the provider is connected in **Dashboard → Providers**
|
||||
- Уверете се, че използвате правилния префикс: `deepgram/nova-3` или `assemblyai/best`
|
||||
- Проверете дали доставчикът е свързан в**Табло → Доставчици**### Транскрипцията се връща празна или е неуспешна
|
||||
|
||||
### Transcription returns empty or fails
|
||||
- Проверете поддържаните аудио формати: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Уверете се, че размерът на файла е в границите на доставчика (обикновено < 25MB)
|
||||
- Проверете валидността на API ключа на доставчика в картата на доставчика---## Translator Debugging
|
||||
|
||||
- Check supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Verify file size is within provider limits (typically < 25MB)
|
||||
- Check provider API key validity in the provider card
|
||||
Използвайте**Таблица за управление → Преводач**за отстраняване на грешки при проблеми с превод на формат:
|
||||
|
||||
---
|
||||
| Режим | Кога да използвате |
|
||||
| ------------------- | ------------------------------------------------------------------------------------------------------------- | ------------------------ |
|
||||
| **Детска площадка** | Сравнете входно/изходните формати един до друг — поставете неуспешна заявка, за да видите как се превежда |
|
||||
| **Чат тестер** | Изпращайте съобщения на живо и проверете допълнителен полезен продукт на заявка/отговор, включително заглавки |
|
||||
| **Тестова стенда** | Изпълнете групови тестове в комбинации от формати, за да откриете кои преводи са нарушени |
|
||||
| **Монитор на живо** | Гледайте потока на заявките в реално време, за да уловите периодични проблеми с превод | ### Common format issues |
|
||||
|
||||
## Translator Debugging
|
||||
-**Тагове за мислене не се появяват**— Проверете дали целевият доставчик поддържа мисленето и настройката на бюджета за мислене -**Отпадане на извикванията на инструментите**— Някои преводи на формати могат да премахнат неподдържаните полета; потвърдете в режим Playground -**Липсва системна подкана**— Клод и Джемини обработват системните подкани по различен начин; проверка на резултата за превод -**SDK връща необработен низ вместо валиден обект**— Коригирано във v1.1.0: дезинфектантът за отговор вече премахва нестандартните полета (`x_groq`, `usage_breakdown` и т.н.), които предизвикват неуспешно пускане на OpenAI SDK Pydantic -**GLM/ERNIE отхвърля `системна` роля**— Коригирано във v1.1.0: нормализаторът на ролите автоматично обединява системни съобщения в потребителски съобщения за несъвместими модели
|
||||
|
||||
Use **Dashboard → Translator** to debug format translation issues:
|
||||
|
||||
| Mode | When to Use |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------- |
|
||||
| **Playground** | Compare input/output formats side by side — paste a failing request to see how it translates |
|
||||
| **Chat Tester** | Send live messages and inspect the full request/response payload including headers |
|
||||
| **Test Bench** | Run batch tests across format combinations to find which translations are broken |
|
||||
| **Live Monitor** | Watch real-time request flow to catch intermittent translation issues |
|
||||
|
||||
### Common format issues
|
||||
|
||||
- **Thinking tags not appearing** — Check if the target provider supports thinking and the thinking budget setting
|
||||
- **Tool calls dropping** — Some format translations may strip unsupported fields; verify in Playground mode
|
||||
- **System prompt missing** — Claude and Gemini handle system prompts differently; check translation output
|
||||
- **SDK returns raw string instead of object** — 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`
|
||||
|
||||
---
|
||||
|
||||
## Resilience Settings
|
||||
- Ролята на**`разработчик` не е разпозната**— Коригирано във v1.1.0: автоматично се преобразува в `системата` за доставчици, не е с OpenAI -**`json_schema` не работи с Gemini**— Коригирано във v1.1.0: `response_format` вече се преобразува в `responseMimeType` + `responseSchema` на Gemini---## Resilience Settings
|
||||
|
||||
### Auto rate-limit not triggering
|
||||
|
||||
- Auto rate-limit only applies to API key providers (not OAuth/subscription)
|
||||
- Verify **Settings → Resilience → Provider Profiles** has auto-rate-limit enabled
|
||||
- Check if the provider returns `429` status codes or `Retry-After` headers
|
||||
- Автоматичното ограничение на скоростта се прилага само за доставчици на API ключове (без OAuth/абонамент)
|
||||
- Уверете се, че**Настройки → Устойчивост → Профили на доставчици**има активиран автоматичен лимит на скоростта
|
||||
- Проверете дали доставчикът връща кодове за състояние `429` или заглавки `Retry-After`### Tuning exponential backoff
|
||||
|
||||
### Tuning exponential backoff
|
||||
Профилът на доставчика поддържа тези настройки:
|
||||
|
||||
Provider profiles support these settings:
|
||||
-**Базово плащане**— Първоначално време на изчакване след първото увреждане (по подразбиране: 1s) -**Максимално заплащане**— Максимално ограничение на времето за изчакване (по подразбиране: 30 секунди) -**Множител**— Колко да се увеличи закъснението за последователен отказ (по подразбиране: 2x)### Anti-thundering herd
|
||||
|
||||
- **Base delay** — Initial wait time after first failure (default: 1s)
|
||||
- **Max delay** — Maximum wait time cap (default: 30s)
|
||||
- **Multiplier** — How much to increase delay per consecutive failure (default: 2x)
|
||||
Когато много едновременни заявки се появяват на доставчика с ограничена скорост, OmniRoute използва mutex + автоматично регулиране на скоростта, за да сериализира заявките и да предотврати каскадни грешки. Това е автоматично за доставчиците на API ключове.---## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
|
||||
### Anti-thundering herd
|
||||
Някои потребители на OmniRoute поставят шлюза пред RAG или агент стекове. В тези настройки е обичайно да се вижда отстранен модел: OmniRoute изглежда здрав (доставчиците работят, профилите за маршрутизиране са добри, няма предупреждения за ограничение на скоростта), но крайният отговор е още по-грешен.
|
||||
|
||||
When many concurrent requests hit a rate-limited provider, OmniRoute uses mutex + auto rate-limiting to serialize requests and prevent cascading failures. This is automatic for API key providers.
|
||||
На практика тези инциденти идват от тръбопровода RAG надолу по веригата, а не от вашия шлюз.
|
||||
|
||||
---
|
||||
Ако търсите отделен речник, който да напише тези повреди, можете да използвате WFGY ProblemMap, външен текстов ресурс за лиценз на MIT, който дефинира шестнадесет повтарящи се модели при отказ на RAG / LLM. На високо ниво: обхваща
|
||||
|
||||
## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
- отклонение при извличане и нарушени контекстни граници
|
||||
- празни или остарели индекси и векторни хранилища
|
||||
- вграждане срещу семантично несъответствие
|
||||
- бързо сглобяване и проблеми с контекстния прозорец
|
||||
- логически колапс и изключително самоуверени отговори
|
||||
- дълга верига и неуспехи в координацията на агента
|
||||
- мултиагентна памет и дрейф на ролите
|
||||
- проблеми с внедряването и подреждането на избраното зареждане
|
||||
|
||||
Some OmniRoute users place the gateway in front of RAG or agent stacks. In those setups it is common to see a strange pattern: OmniRoute looks healthy (providers up, routing profiles ok, no rate limit alerts) but the final answer is still wrong.
|
||||
Идеята е проста:
|
||||
|
||||
In practice these incidents usually come from the downstream RAG pipeline, not from the gateway itself.
|
||||
1. Когато проучвате лош отговор, заснемете:
|
||||
- потребителска задача и заявка
|
||||
- комбо маршрут или доставчик в OmniRoute
|
||||
- всеки RAG контекст, използван надолу по веригата (извлечени документи, извиквания на инструменти и т.н.)
|
||||
2. Съставете инцидента с едно или две номера на картата на проблемите на WFGY („No.1“ … „No.16“).
|
||||
3. Съхранявайте номера във вашето собствено табло, runbook или инструмент за проследяване на инциденти до регистриране на файлове в OmniRoute.
|
||||
4. Съществувате WFGY страница, за да решите дали трябва да промените своя RAG стек, ретривър или стратегия за маршрутизиране.
|
||||
|
||||
If you want a shared vocabulary to describe those failures you can use the WFGY ProblemMap, an external MIT license text resource that defines sixteen recurring RAG / LLM failure patterns. At a high level it covers:
|
||||
|
||||
- retrieval drift and broken context boundaries
|
||||
- empty or stale indexes and vector stores
|
||||
- embedding versus semantic mismatch
|
||||
- prompt assembly and context window issues
|
||||
- logic collapse and overconfident answers
|
||||
- long chain and agent coordination failures
|
||||
- multi agent memory and role drift
|
||||
- deployment and bootstrap ordering problems
|
||||
|
||||
The idea is simple:
|
||||
|
||||
1. When you investigate a bad response, capture:
|
||||
- user task and request
|
||||
- route or provider combo in OmniRoute
|
||||
- any RAG context used downstream (retrieved documents, tool calls, etc)
|
||||
2. Map the incident to one or two WFGY ProblemMap numbers (`No.1` … `No.16`).
|
||||
3. Store the number in your own dashboard, runbook, or incident tracker next to the OmniRoute logs.
|
||||
4. Use the corresponding WFGY page to decide whether you need to change your RAG stack, retriever, or routing strategy.
|
||||
|
||||
Full text and concrete recipes live here (MIT license, text only):
|
||||
Пълният текст и конкретните рецепти се намират тук (лиценз на MIT, само текстът):
|
||||
|
||||
[WFGY ProblemMap README](https://github.com/onestardao/WFGY/blob/main/ProblemMap/README.md)
|
||||
|
||||
You can ignore this section if you do not run RAG or agent pipelines behind OmniRoute.
|
||||
Можете да пренебрегнете този раздел, ако не изпълните RAG или конвейери на агенти зад OmniRoute.---## Still Stuck?
|
||||
|
||||
---
|
||||
|
||||
## Still Stuck?
|
||||
|
||||
- **GitHub Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Architecture**: See [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) for internal details
|
||||
- **API Reference**: See [`docs/API_REFERENCE.md`](API_REFERENCE.md) for all endpoints
|
||||
- **Health Dashboard**: Check **Dashboard → Health** for real-time system status
|
||||
- **Translator**: Use **Dashboard → Translator** to debug format issues
|
||||
-**Проблеми с GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**Архитектура**: Вижте [`docs/ARCHITECTURE.md`](ARCHITECTURE.md) за вътрешни подробности -**API Reference**: Вижте [`docs/API_REFERENCE.md`](API_REFERENCE.md) за всички крайни точки -**Таблица за управление на здравето**: Проверете**Таблица за управление → Здраве**за състоянието на системата в реално време -**Преводач**: Използвайте**Табло за управление → Преводач**за отстраняване на грешки във форматирането
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,50 +1,39 @@
|
||||
# OmniRoute — Deployment Guide on VM with Cloudflare (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/VM_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/VM_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/VM_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/VM_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/VM_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/VM_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/VM_DEPLOYMENT_GUIDE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/VM_DEPLOYMENT_GUIDE.md) · 🇪🇸 [es](../../es/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇷 [fr](../../fr/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇪 [de](../../de/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇹 [it](../../it/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇺 [ru](../../ru/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/VM_DEPLOYMENT_GUIDE.md) · 🇯🇵 [ja](../../ja/docs/VM_DEPLOYMENT_GUIDE.md) · 🇰🇷 [ko](../../ko/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇦 [ar](../../ar/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [hi](../../hi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇳 [in](../../in/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇭 [th](../../th/docs/VM_DEPLOYMENT_GUIDE.md) · 🇻🇳 [vi](../../vi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇩 [id](../../id/docs/VM_DEPLOYMENT_GUIDE.md) · 🇲🇾 [ms](../../ms/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇱 [nl](../../nl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇱 [pl](../../pl/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇪 [sv](../../sv/docs/VM_DEPLOYMENT_GUIDE.md) · 🇳🇴 [no](../../no/docs/VM_DEPLOYMENT_GUIDE.md) · 🇩🇰 [da](../../da/docs/VM_DEPLOYMENT_GUIDE.md) · 🇫🇮 [fi](../../fi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇹 [pt](../../pt/docs/VM_DEPLOYMENT_GUIDE.md) · 🇷🇴 [ro](../../ro/docs/VM_DEPLOYMENT_GUIDE.md) · 🇭🇺 [hu](../../hu/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇬 [bg](../../bg/docs/VM_DEPLOYMENT_GUIDE.md) · 🇸🇰 [sk](../../sk/docs/VM_DEPLOYMENT_GUIDE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/VM_DEPLOYMENT_GUIDE.md) · 🇮🇱 [he](../../he/docs/VM_DEPLOYMENT_GUIDE.md) · 🇵🇭 [phi](../../phi/docs/VM_DEPLOYMENT_GUIDE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/VM_DEPLOYMENT_GUIDE.md) · 🇨🇿 [cs](../../cs/docs/VM_DEPLOYMENT_GUIDE.md) · 🇹🇷 [tr](../../tr/docs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
|
||||
Пълно ръководство за инсталиране и конфигуриране на OmniRoute на VM (VPS) с домейн, управлявано чрез Cloudflare.---## Prerequisites
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Item | Minimum | Recommended |
|
||||
| Артикул | Минимум | Препоръчва се |
|
||||
| ---------- | ------------------------ | ---------------- |
|
||||
| **CPU** | 1 vCPU | 2 vCPU |
|
||||
| **RAM** | 1 GB | 2 GB |
|
||||
| **Disk** | 10 GB SSD | 25 GB SSD |
|
||||
| **Диск** | 10 GB SSD | 25 GB SSD |
|
||||
| **OS** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|
||||
| **Domain** | Registered on Cloudflare | — |
|
||||
| **Docker** | Docker Engine 24+ | Docker 27+ |
|
||||
| **Домейн** | Регистриран в Cloudflare | — |
|
||||
| **Докер** | Docker Engine 24+ | Докер 27+ |
|
||||
|
||||
**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
|
||||
|
||||
---
|
||||
|
||||
## 1. Configure the VM
|
||||
**Тествани доставчици**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.---## 1. Configure the VM
|
||||
|
||||
### 1.1 Create the instance
|
||||
|
||||
On your preferred VPS provider:
|
||||
По предпочитания от вас VPS доставчик:
|
||||
|
||||
- Choose Ubuntu 24.04 LTS
|
||||
- Select the minimum plan (1 vCPU / 1 GB RAM)
|
||||
- Set a strong root password or configure SSH key
|
||||
- Note the **public IP** (e.g., `203.0.113.10`)
|
||||
- Изберете Ubuntu 24.04 LTS
|
||||
- Изберете минималния план (1 vCPU / 1 GB RAM)
|
||||
- Задайте силна root парола или конфигурирайте SSH ключ
|
||||
- Обърнете внимание на**публичния IP**(напр. `203.0.113.10`)### 1.2 Свързване чрез SSH```bash
|
||||
ssh root@203.0.113.10
|
||||
|
||||
### 1.2 Connect via SSH
|
||||
|
||||
```bash
|
||||
ssh root@203.0.113.10
|
||||
```
|
||||
````
|
||||
|
||||
### 1.3 Update the system
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
````
|
||||
|
||||
### 1.4 Install Docker
|
||||
|
||||
@@ -78,11 +67,7 @@ ufw allow 443/tcp # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
> **Tip**: For maximum security, restrict ports 80 and 443 to Cloudflare IPs only. See the [Advanced Security](#advanced-security) section.
|
||||
|
||||
---
|
||||
|
||||
## 2. Install OmniRoute
|
||||
> **Съвет**: За максимална сигурност ограничете портове 80 и 443 само до IP адреса на Cloudflare. Вижте раздела [Разширена сигурност](#advanced-security).---## 2. Install OmniRoute
|
||||
|
||||
### 2.1 Create configuration directory
|
||||
|
||||
@@ -122,126 +107,118 @@ NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
|
||||
EOF
|
||||
```
|
||||
|
||||
> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
|
||||
|
||||
### 2.3 Start the container
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
> ⚠️**ВАЖНО**: Генерирайте уникални секретни ключове! Използвайте `openssl rand -hex 32` за всеки ключ.### 2.3 Стартирайте контейнера```bash
|
||||
> docker pull diegosouzapw/omniroute:latest
|
||||
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
|
||||
````
|
||||
|
||||
### 2.4 Verify that it is running
|
||||
|
||||
```bash
|
||||
docker ps | grep omniroute
|
||||
docker logs omniroute --tail 20
|
||||
```
|
||||
````
|
||||
|
||||
It should display: `[DB] SQLite database ready` and `listening on port 20128`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Configure nginx (Reverse Proxy)
|
||||
Трябва да се покаже: „[DB] SQLite база данни е готова“ и „слушане на порт 20128“.---## 3. Configure nginx (Reverse Proxy)
|
||||
|
||||
### 3.1 Generate SSL certificate (Cloudflare Origin)
|
||||
|
||||
In the Cloudflare dashboard:
|
||||
В таблото за управление на Cloudflare:
|
||||
|
||||
1. Go to **SSL/TLS → Origin Server**
|
||||
2. Click **Create Certificate**
|
||||
3. Keep the defaults (15 years, \*.yourdomain.com)
|
||||
4. Copy the **Origin Certificate** and the **Private Key**
|
||||
1. Отидете на**SSL/TLS → Origin Server**
|
||||
2. Щракнете върху**Създаване на сертификат**
|
||||
3. Запазете настройките по подразбиране (15 години, \*.yourdomain.com)
|
||||
4. Копирайте**Сертификата за произход**и**Личния ключ**```bash
|
||||
mkdir -p /etc/nginx/ssl
|
||||
|
||||
```bash
|
||||
mkdir -p /etc/nginx/ssl
|
||||
# Поставете сертификата
|
||||
|
||||
# Paste the certificate
|
||||
nano /etc/nginx/ssl/origin.crt
|
||||
|
||||
# Paste the private key
|
||||
# Поставете личния ключ
|
||||
|
||||
nano /etc/nginx/ssl/origin.key
|
||||
|
||||
chmod 600 /etc/nginx/ssl/origin.key
|
||||
```
|
||||
chmod 600 /etc/nginx/ssl/origin.key```
|
||||
|
||||
### 3.2 Nginx Configuration
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
|
||||
# Default server — blocks direct access via IP
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
````bash
|
||||
cat > /etc/nginx/sites-available/omniroute << 'NGINX'
|
||||
# Сървър по подразбиране — блокира директен достъп през IP
|
||||
сървър {
|
||||
слушане 80 default_server;
|
||||
слушам [::]:80 default_server;
|
||||
слушане 443 ssl default_server;
|
||||
слушам [::]:443 ssl default_server;
|
||||
ssl_сертификат /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
server_name _;
|
||||
return 444;
|
||||
име_на_сървър_;
|
||||
връщане 444;
|
||||
}
|
||||
|
||||
# OmniRoute — HTTPS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name llms.yourdomain.com; # Change to your domain
|
||||
сървър {
|
||||
слушане 443 ssl;
|
||||
слушам [::]:443 ssl;
|
||||
сървър_име llms.вашият домейн.com; # Промяна на вашия домейн
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_сертификат /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
|
||||
client_max_body_size 100M;
|
||||
|
||||
location / {
|
||||
местоположение / {
|
||||
proxy_pass http://127.0.0.1:20128;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Хост $хост;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $схема;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection “upgrade”;
|
||||
# Поддръжка на WebSocket
|
||||
proxy_http_версия 1.1;
|
||||
proxy_set_header Надграждане $http_upgrade;
|
||||
proxy_set_header Връзка „надграждане“;
|
||||
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
# SSE (Изпратени от сървъра събития) — поточно предаване на AI отговори
|
||||
proxy_buffering изключено;
|
||||
proxy_cache изключен;
|
||||
proxy_read_timeout 600s;
|
||||
proxy_send_timeout 600s;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTP → HTTPS redirect
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name llms.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
# HTTP → HTTPS пренасочване
|
||||
сървър {
|
||||
слушам 80;
|
||||
слушам [::]:80;
|
||||
сървър_име llms.вашият домейн.com;
|
||||
връщане 301 https://$server_name$request_uri;
|
||||
}
|
||||
NGINX
|
||||
```
|
||||
NGINX```
|
||||
|
||||
### 3.3 Enable and Test
|
||||
Поддържайте времето за изчакване на обратен прокси поток в съответствие с вашите OmniRoute timeout env vars. Ако рейзнете
|
||||
`FETCH_TIMEOUT_MS` / `STREAM_IDLE_TIMEOUT_MS`, повишаване на `proxy_read_timeout` / `proxy_send_timeout`
|
||||
над същия праг.### 3.3 Enable and Test
|
||||
|
||||
```bash
|
||||
# Remove default configuration
|
||||
# Премахнете конфигурацията по подразбиране
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Enable OmniRoute
|
||||
# Активирайте OmniRoute
|
||||
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
|
||||
|
||||
# Test and reload
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
# Тествайте и презаредете
|
||||
nginx -t && systemctl презареди nginx```
|
||||
|
||||
---
|
||||
|
||||
@@ -249,30 +226,25 @@ nginx -t && systemctl reload nginx
|
||||
|
||||
### 4.1 Add DNS record
|
||||
|
||||
In the Cloudflare dashboard → DNS:
|
||||
В таблото за управление на Cloudflare → DNS:
|
||||
|
||||
| Type | Name | Content | Proxy |
|
||||
| Тип | Име | Съдържание | Прокси |
|
||||
| ---- | ------ | ---------------------- | ---------- |
|
||||
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
|
||||
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Проксиран |### 4.2 Configure SSL
|
||||
|
||||
### 4.2 Configure SSL
|
||||
Под**SSL/TLS → Общ преглед**:
|
||||
|
||||
Under **SSL/TLS → Overview**:
|
||||
- Режим:**Пълен (строг)**
|
||||
|
||||
- Mode: **Full (Strict)**
|
||||
Под**SSL/TLS → Edge Certificates**:
|
||||
|
||||
Under **SSL/TLS → Edge Certificates**:
|
||||
|
||||
- Always Use HTTPS: ✅ On
|
||||
- Minimum TLS Version: TLS 1.2
|
||||
- Automatic HTTPS Rewrites: ✅ On
|
||||
|
||||
### 4.3 Testing
|
||||
- Винаги използвайте HTTPS: ✅ Вкл
|
||||
- Минимална TLS версия: TLS 1.2
|
||||
- Автоматично пренаписване на HTTPS: ✅ Включено### 4.3 Testing
|
||||
|
||||
```bash
|
||||
curl -sI https://llms.seudominio.com/health
|
||||
# Should return HTTP/2 200
|
||||
```
|
||||
# Трябва да върне HTTP/2 200```
|
||||
|
||||
---
|
||||
|
||||
@@ -281,41 +253,37 @@ curl -sI https://llms.seudominio.com/health
|
||||
### Upgrade to a new version
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
докер изтегляне diegosouzapw/omniroute: най-нов
|
||||
docker stop omniroute && docker rm omniroute
|
||||
docker run -d --name omniroute --restart unless-stopped \
|
||||
--env-file /opt/omniroute/.env \
|
||||
--env-файл /opt/omniroute/.env \
|
||||
-p 20128:20128 \
|
||||
-v omniroute-data:/app/data \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
diegosouzapw/omniroute: най-нов```
|
||||
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
docker logs -f omniroute # Real-time stream
|
||||
docker logs omniroute --tail 50 # Last 50 lines
|
||||
```
|
||||
docker logs -f omniroute # Поток в реално време
|
||||
докер регистрира omniroute --tail 50 # Последните 50 реда```
|
||||
|
||||
### Manual database backup
|
||||
|
||||
```bash
|
||||
# Copy data from the volume to the host
|
||||
docker cp omniroute:/app/data ./backup-$(date +%F)
|
||||
# Копирайте данни от тома към хоста
|
||||
docker cp omniroute:/app/data ./backup-$(дата +%F)
|
||||
|
||||
# Or compress the entire volume
|
||||
# Или компресирайте целия обем
|
||||
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
alpine tar czf /backup/omniroute-data-$(date +%F).tar.gz /data
|
||||
```
|
||||
alpine tar czf /backup/omniroute-data-$(дата +%F).tar.gz /данни```
|
||||
|
||||
### Restore from backup
|
||||
|
||||
```bash
|
||||
docker stop omniroute
|
||||
докер стоп omniroute
|
||||
docker run --rm -v omniroute-data:/data -v $(pwd):/backup \
|
||||
alpine sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
|
||||
docker start omniroute
|
||||
```
|
||||
докер стартира omniroute```
|
||||
|
||||
---
|
||||
|
||||
@@ -324,33 +292,30 @@ docker start omniroute
|
||||
### Restrict nginx to Cloudflare IPs
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
|
||||
# Cloudflare IPv4 ranges — update periodically
|
||||
cat > /etc/nginx/cloudflare-ips.conf << 'CF'
|
||||
# Cloudflare IPv4 диапазони — актуализирайте периодично
|
||||
# https://www.cloudflare.com/ips-v4/
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
set_real_ip_from 103.22.200.0/22;
|
||||
set_real_ip_from 103.31.4.0/22;
|
||||
set_real_ip_from 141.101.64.0/18;
|
||||
set_real_ip_from 108.162.192.0/18;
|
||||
set_real_ip_from 190.93.240.0/20;
|
||||
set_real_ip_from 188.114.96.0/20;
|
||||
set_real_ip_from 197.234.240.0/22;
|
||||
set_real_ip_from 198.41.128.0/17;
|
||||
set_real_ip_от 103.21.244.0/22;
|
||||
set_real_ip_от 103.22.200.0/22;
|
||||
set_real_ip_от 103.31.4.0/22;
|
||||
set_real_ip_от 141.101.64.0/18;
|
||||
set_real_ip_от 108.162.192.0/18;
|
||||
set_real_ip_от 190.93.240.0/20;
|
||||
set_real_ip_от 188.114.96.0/20;
|
||||
set_real_ip_от 197.234.240.0/22;
|
||||
set_real_ip_от 198.41.128.0/17;
|
||||
set_real_ip_from 162.158.0.0/15;
|
||||
set_real_ip_from 104.16.0.0/13;
|
||||
set_real_ip_from 104.24.0.0/14;
|
||||
set_real_ip_from 172.64.0.0/13;
|
||||
set_real_ip_from 131.0.72.0/22;
|
||||
real_ip_header CF-Connecting-IP;
|
||||
CF
|
||||
```
|
||||
real_ip_header CF-Свързване-IP;
|
||||
CF```
|
||||
|
||||
Add the following to `nginx.conf` inside the `http {}` block:
|
||||
|
||||
```nginx
|
||||
Добавете следното към `nginx.conf` в блока `http {}`:```nginx
|
||||
include /etc/nginx/cloudflare-ips.conf;
|
||||
```
|
||||
````
|
||||
|
||||
### Install fail2ban
|
||||
|
||||
@@ -379,25 +344,22 @@ netfilter-persistent save
|
||||
|
||||
## 7. Deploy to Cloudflare Workers (Optional)
|
||||
|
||||
For remote access via Cloudflare Workers (without exposing the VM directly):
|
||||
За отдалечен достъп чрез Cloudflare Workers (без директно излагане на VM):```bash
|
||||
|
||||
# В локалното хранилище
|
||||
|
||||
```bash
|
||||
# In the local repository
|
||||
cd omnirouteCloud
|
||||
npm install
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
npm инсталирайте
|
||||
влизане в npx wrangler
|
||||
разгръщане на npx wrangler```
|
||||
|
||||
See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
|
||||
---
|
||||
Вижте пълната документация на [omnirouteCloud/README.md](../omnirouteCloud/README.md).---
|
||||
|
||||
## Port Summary
|
||||
|
||||
| Port | Service | Access |
|
||||
| ----- | ----------- | -------------------------- |
|
||||
| 22 | SSH | Public (with fail2ban) |
|
||||
| 80 | nginx HTTP | Redirect → HTTPS |
|
||||
| 443 | nginx HTTPS | Via Cloudflare Proxy |
|
||||
| 20128 | OmniRoute | Localhost only (via nginx) |
|
||||
| Пристанище | Обслужване | Достъп |
|
||||
| ---------- | ----------- | ------------------------------ |
|
||||
| 22 | SSH | Публичен (с fail2ban) |
|
||||
| 80 | nginx HTTP | Пренасочване → HTTPS |
|
||||
| 443 | nginx HTTPS | Чрез прокси Cloudflare |
|
||||
| 20128 | OmniRoute | Само локален хост (чрез nginx) |
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# OmniRoute A2A Server (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../../../src/lib/a2a/README.md) · 🇪🇸 [es](../../../../es/src/lib/a2a/README.md) · 🇫🇷 [fr](../../../../fr/src/lib/a2a/README.md) · 🇩🇪 [de](../../../../de/src/lib/a2a/README.md) · 🇮🇹 [it](../../../../it/src/lib/a2a/README.md) · 🇷🇺 [ru](../../../../ru/src/lib/a2a/README.md) · 🇨🇳 [zh-CN](../../../../zh-CN/src/lib/a2a/README.md) · 🇯🇵 [ja](../../../../ja/src/lib/a2a/README.md) · 🇰🇷 [ko](../../../../ko/src/lib/a2a/README.md) · 🇸🇦 [ar](../../../../ar/src/lib/a2a/README.md) · 🇮🇳 [in](../../../../in/src/lib/a2a/README.md) · 🇹🇭 [th](../../../../th/src/lib/a2a/README.md) · 🇻🇳 [vi](../../../../vi/src/lib/a2a/README.md) · 🇮🇩 [id](../../../../id/src/lib/a2a/README.md) · 🇲🇾 [ms](../../../../ms/src/lib/a2a/README.md) · 🇳🇱 [nl](../../../../nl/src/lib/a2a/README.md) · 🇵🇱 [pl](../../../../pl/src/lib/a2a/README.md) · 🇸🇪 [sv](../../../../sv/src/lib/a2a/README.md) · 🇳🇴 [no](../../../../no/src/lib/a2a/README.md) · 🇩🇰 [da](../../../../da/src/lib/a2a/README.md) · 🇫🇮 [fi](../../../../fi/src/lib/a2a/README.md) · 🇵🇹 [pt](../../../../pt/src/lib/a2a/README.md) · 🇷🇴 [ro](../../../../ro/src/lib/a2a/README.md) · 🇭🇺 [hu](../../../../hu/src/lib/a2a/README.md) · 🇧🇬 [bg](../../../../bg/src/lib/a2a/README.md) · 🇸🇰 [sk](../../../../sk/src/lib/a2a/README.md) · 🇺🇦 [uk-UA](../../../../uk-UA/src/lib/a2a/README.md) · 🇮🇱 [he](../../../../he/src/lib/a2a/README.md) · 🇵🇭 [phi](../../../../phi/src/lib/a2a/README.md) · 🇧🇷 [pt-BR](../../../../pt-BR/src/lib/a2a/README.md) · 🇨🇿 [cs](../../../../cs/src/lib/a2a/README.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../../../src/lib/a2a/README.md) · 🇪🇸 [es](../../../../es/src/lib/a2a/README.md) · 🇫🇷 [fr](../../../../fr/src/lib/a2a/README.md) · 🇩🇪 [de](../../../../de/src/lib/a2a/README.md) · 🇮🇹 [it](../../../../it/src/lib/a2a/README.md) · 🇷🇺 [ru](../../../../ru/src/lib/a2a/README.md) · 🇨🇳 [zh-CN](../../../../zh-CN/src/lib/a2a/README.md) · 🇯🇵 [ja](../../../../ja/src/lib/a2a/README.md) · 🇰🇷 [ko](../../../../ko/src/lib/a2a/README.md) · 🇸🇦 [ar](../../../../ar/src/lib/a2a/README.md) · 🇮🇳 [hi](../../../../hi/src/lib/a2a/README.md) · 🇮🇳 [in](../../../../in/src/lib/a2a/README.md) · 🇹🇭 [th](../../../../th/src/lib/a2a/README.md) · 🇻🇳 [vi](../../../../vi/src/lib/a2a/README.md) · 🇮🇩 [id](../../../../id/src/lib/a2a/README.md) · 🇲🇾 [ms](../../../../ms/src/lib/a2a/README.md) · 🇳🇱 [nl](../../../../nl/src/lib/a2a/README.md) · 🇵🇱 [pl](../../../../pl/src/lib/a2a/README.md) · 🇸🇪 [sv](../../../../sv/src/lib/a2a/README.md) · 🇳🇴 [no](../../../../no/src/lib/a2a/README.md) · 🇩🇰 [da](../../../../da/src/lib/a2a/README.md) · 🇫🇮 [fi](../../../../fi/src/lib/a2a/README.md) · 🇵🇹 [pt](../../../../pt/src/lib/a2a/README.md) · 🇷🇴 [ro](../../../../ro/src/lib/a2a/README.md) · 🇭🇺 [hu](../../../../hu/src/lib/a2a/README.md) · 🇧🇬 [bg](../../../../bg/src/lib/a2a/README.md) · 🇸🇰 [sk](../../../../sk/src/lib/a2a/README.md) · 🇺🇦 [uk-UA](../../../../uk-UA/src/lib/a2a/README.md) · 🇮🇱 [he](../../../../he/src/lib/a2a/README.md) · 🇵🇭 [phi](../../../../phi/src/lib/a2a/README.md) · 🇧🇷 [pt-BR](../../../../pt-BR/src/lib/a2a/README.md) · 🇨🇿 [cs](../../../../cs/src/lib/a2a/README.md) · 🇹🇷 [tr](../../../../tr/src/lib/a2a/README.md)
|
||||
|
||||
---
|
||||
|
||||
> **Agent-to-Agent Protocol v0.3** — Enables any AI agent to use OmniRoute as an intelligent routing agent via JSON-RPC 2.0.
|
||||
> **Agent-to-Agent Protocol v0.3**— Позволява на всеки AI агент да използва OmniRoute като интелигентен агент за маршрутизиране чрез JSON-RPC 2.0.
|
||||
|
||||
The A2A Server exposes OmniRoute as a **first-class agent** that other agents can discover, delegate tasks to, and collaborate with using the [A2A Protocol](https://google.github.io/A2A/).
|
||||
|
||||
---
|
||||
Сървърът A2A излага OmniRoute като**първокласен агент**, който други агенти могат да открият, да делегират задачи и да си сътрудничат с помощта на [A2A протокола](https://google.github.io/A2A/).---
|
||||
|
||||
## Архитектура
|
||||
|
||||
@@ -43,15 +41,12 @@ The A2A Server exposes OmniRoute as a **first-class agent** that other agents ca
|
||||
|
||||
### Agent Discovery
|
||||
|
||||
Every A2A-compatible agent exposes an **Agent Card** at `/.well-known/agent.json`:
|
||||
|
||||
```bash
|
||||
Всеки A2A-съвместим агент излага**Карта на агент**в `/.well-known/agent.json`:```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
**Response:**
|
||||
````
|
||||
|
||||
```json
|
||||
**Отговор:**```json
|
||||
{
|
||||
"name": "OmniRoute",
|
||||
"description": "Intelligent AI gateway with auto-routing across 50+ providers",
|
||||
@@ -88,7 +83,7 @@ curl http://localhost:20128/.well-known/agent.json
|
||||
"apiKeyHeader": "Authorization"
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -96,27 +91,24 @@ curl http://localhost:20128/.well-known/agent.json
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Send a message to a skill and receive the complete response.
|
||||
|
||||
```bash
|
||||
Изпратете съобщение до умение и получете пълния отговор.```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a Python hello world"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a Python hello world"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
|
||||
**Response:**
|
||||
````
|
||||
|
||||
```json
|
||||
**Отговор:**```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
@@ -133,36 +125,33 @@ curl -X POST http://localhost:20128/a2a \
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
### `message/stream` — SSE Streaming
|
||||
|
||||
Same as `message/send` but returns Server-Sent Events for real-time streaming.
|
||||
|
||||
```bash
|
||||
Същото като `message/send`, но връща изпратени от сървъра събития за поточно предаване в реално време.```bash
|
||||
curl -N -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
|
||||
**SSE Events:**
|
||||
````
|
||||
|
||||
```
|
||||
**SSE събития:**```
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"Quantum computing..."}}}
|
||||
|
||||
: heartbeat 2026-03-04T21:00:00Z
|
||||
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
|
||||
```
|
||||
````
|
||||
|
||||
### `tasks/get` — Query Task Status
|
||||
|
||||
@@ -188,40 +177,36 @@ curl -X POST http://localhost:20128/a2a \
|
||||
|
||||
### `smart-routing`
|
||||
|
||||
Routes prompts through OmniRoute's intelligent pipeline with full observability.
|
||||
Подкани за маршрути чрез интелигентния тръбопровод на OmniRoute с пълна видимост.
|
||||
|
||||
**Parameters (in `metadata`):**
|
||||
**Параметри (в `метаданни`):**
|
||||
|
||||
| Parameter | Type | Default | Description |
|
||||
| --------- | -------- | ------------ | ---------------------------------------------------------------------------------------- |
|
||||
| `model` | `string` | `"auto"` | Target model (e.g., `claude-sonnet-4`, `gpt-4o`, `auto`) |
|
||||
| `combo` | `string` | active combo | Specific combo to route through |
|
||||
| `budget` | `number` | none | Maximum cost in USD for this request |
|
||||
| `role` | `string` | none | Task role hint: `coding`, `review`, `planning`, `analysis`, `debugging`, `documentation` |
|
||||
| Параметър | Тип | По подразбиране | Описание |
|
||||
| --------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `модел` | `низ` | `"автоматично"` | Целеви модел (напр. `claude-sonnet-4`, `gpt-4o`, `auto`) |
|
||||
| `комбо` | `низ` | активно комбо | Специфична комбинация за маршрут през |
|
||||
| `бюджет` | `номер` | няма | Максимална цена в USD за тази заявка |
|
||||
| `роля` | `низ` | няма | Подсказка за роля на задача: `кодиране`, `преглед`, `планиране`, `анализ`, `отстраняване на грешки`, `документация` |
|
||||
|
||||
**Returns:**
|
||||
**Връща:**
|
||||
|
||||
| Field | Description |
|
||||
| ------------------------------ | --------------------------------------------------------- |
|
||||
| `artifacts[].content` | The LLM response text |
|
||||
| `metadata.routing_explanation` | Human-readable explanation of routing decision |
|
||||
| `metadata.cost_envelope` | Estimated vs actual cost with currency |
|
||||
| `metadata.resilience_trace` | Array of events (primary_selected, fallback_needed, etc.) |
|
||||
| `metadata.policy_verdict` | Whether the request was allowed and why |
|
||||
| Поле | Описание |
|
||||
| ------------------------------ | ------------------------------------------------------------- | ---------------------- |
|
||||
| `артефакти[].съдържание` | Текстът на отговора на LLM |
|
||||
| `metadata.routing_explanation` | Разбираемо за човека обяснение на решението за маршрутизиране |
|
||||
| `metadata.cost_envelope` | Прогнозна срещу действителна цена с валута |
|
||||
| `metadata.resilience_trace` | Масив от събития (primary_selected, fallback_needed и т.н.) |
|
||||
| `metadata.policy_verdict` | Дали искането е разрешено и защо | ### `quota-management` |
|
||||
|
||||
### `quota-management`
|
||||
Отговаря на запитвания на естествен език относно квотите на доставчика.
|
||||
|
||||
Answers natural-language queries about provider quotas.
|
||||
**Типове заявки (изведени от съдържанието на съобщението):**
|
||||
|
||||
**Query types (inferred from message content):**
|
||||
|
||||
| Query Pattern | Response Type |
|
||||
| ---------------------------------------------- | -------------------------------------------------------- |
|
||||
| Contains `"ranking"`, `"most quota"`, `"best"` | Providers ranked by remaining quota |
|
||||
| Contains `"free"`, `"suggest"` | Lists free combos or suggests free-tier providers |
|
||||
| Default | Full quota summary with warnings for low-quota providers |
|
||||
|
||||
---
|
||||
| Модел на заявка | Тип отговор |
|
||||
| --------------------------------------------------------- | ----------------------------------------------------------------------- | --- |
|
||||
| Съдържа `"класиране``, `"най-много квота``, `"най-добър"` | Доставчици, класирани по оставаща квота |
|
||||
| Съдържа `"free"`, `"suggest"` | Изброява безплатни комбинации или предлага доставчици на безплатни нива |
|
||||
| По подразбиране | Пълно резюме на квотата с предупреждения за доставчици с ниска квота | --- |
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
@@ -231,19 +216,17 @@ submitted ──→ working ──→ completed
|
||||
──────────→ cancelled
|
||||
```
|
||||
|
||||
| State | Description |
|
||||
| ----------- | ----------------------------------------------------- |
|
||||
| `submitted` | Task created, queued for execution |
|
||||
| `working` | Skill handler is executing |
|
||||
| `completed` | Execution succeeded, artifacts available |
|
||||
| `failed` | Execution failed or task expired (TTL: 5 min default) |
|
||||
| `cancelled` | Cancelled by client via `tasks/cancel` |
|
||||
| състояние | Описание |
|
||||
| ----------- | --------------------------------------------------------------------------- |
|
||||
| `изпратено` | Задачата е създадена, поставена на опашка за изпълнение |
|
||||
| `работи` | Манипулаторът на умения изпълнява |
|
||||
| `завършен` | Изпълнението е успешно, налични са артефакти |
|
||||
| `неуспешно` | Неуспешно изпълнение или задачата е изтекла (TTL: 5 минути по подразбиране) |
|
||||
| `отменен` | Анулирано от клиент чрез `tasks/cancel` |
|
||||
|
||||
- Terminal states: `completed`, `failed`, `cancelled` (no further transitions)
|
||||
- Expired tasks in `submitted` or `working` are auto-marked as `failed`
|
||||
- Tasks are garbage-collected after 2× TTL
|
||||
|
||||
---
|
||||
- Състояния на терминала: `завършен`, `неуспешен`, `отменен` (без допълнителни преходи)
|
||||
- Изтеклите задачи в „изпратени“ или „работещи“ автоматично се маркират като „неуспешни“
|
||||
- Задачите се събират след 2 × TTL---
|
||||
|
||||
## Client Examples
|
||||
|
||||
@@ -541,15 +524,12 @@ func main() {
|
||||
|
||||
### 🤖 Use Case 1: Multi-Agent Coding Pipeline
|
||||
|
||||
An orchestrator agent delegates code generation to OmniRoute, then passes the output to a review agent.
|
||||
|
||||
```python
|
||||
def coding_pipeline(task: str):
|
||||
# Step 1: Generate code via OmniRoute A2A
|
||||
code_result = a2a_send("smart-routing", [
|
||||
{"role": "user", "content": f"Write production-quality code: {task}"}
|
||||
], metadata={"model": "auto", "role": "coding"})
|
||||
code = code_result["artifacts"][0]["content"]
|
||||
Агент оркестратор делегира генериране на код на OmniRoute, след което предава изхода на агент за преглед.```python
|
||||
def coding_pipeline(task: str): # Step 1: Generate code via OmniRoute A2A
|
||||
code_result = a2a_send("smart-routing", [
|
||||
{"role": "user", "content": f"Write production-quality code: {task}"}
|
||||
], metadata={"model": "auto", "role": "coding"})
|
||||
code = code_result["artifacts"][0]["content"]
|
||||
|
||||
# Step 2: Review the code via OmniRoute A2A (different model)
|
||||
review_result = a2a_send("smart-routing", [
|
||||
@@ -562,13 +542,12 @@ def coding_pipeline(task: str):
|
||||
print(f"Review cost: ${review_result['metadata']['cost_envelope']['actual']}")
|
||||
|
||||
return {"code": code, "review": review}
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### 💡 Use Case 2: Quota-Aware Agent Swarm
|
||||
|
||||
Multiple agents share quota through OmniRoute, using the quota skill to coordinate.
|
||||
|
||||
```python
|
||||
Множество агенти споделят квота чрез OmniRoute, като използват умението за квота за координиране.```python
|
||||
async def quota_aware_agent(agent_name: str, task: str):
|
||||
# Check quota before starting
|
||||
quota = a2a_send("quota-management", [
|
||||
@@ -591,32 +570,30 @@ async def quota_aware_agent(agent_name: str, task: str):
|
||||
print(f"[{agent_name}] Free alternatives: {quota['artifacts'][0]['content']}")
|
||||
|
||||
return result
|
||||
```
|
||||
````
|
||||
|
||||
### 📊 Use Case 3: Real-Time Streaming Dashboard
|
||||
|
||||
A monitoring agent streams responses and displays progress in real-time.
|
||||
|
||||
```typescript
|
||||
Мониторинговият агент предава поточно отговорите и показва напредъка в реално време.```typescript
|
||||
async function streamingDashboard(prompt: string) {
|
||||
const response = await fetch(`${BASE_URL}/a2a`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json", Authorization: `Bearer ${API_KEY}` },
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "dash-1",
|
||||
method: "message/stream",
|
||||
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
|
||||
}),
|
||||
});
|
||||
body: JSON.stringify({
|
||||
jsonrpc: "2.0",
|
||||
id: "dash-1",
|
||||
method: "message/stream",
|
||||
params: { skill: "smart-routing", messages: [{ role: "user", content: prompt }] },
|
||||
}),
|
||||
});
|
||||
|
||||
let totalChunks = 0;
|
||||
const reader = response.body!.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
let totalChunks = 0;
|
||||
const reader = response.body!.getReader();
|
||||
const decoder = new TextDecoder();
|
||||
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
while (true) {
|
||||
const { done, value } = await reader.read();
|
||||
if (done) break;
|
||||
|
||||
for (const line of decoder.decode(value).split("\n")) {
|
||||
if (line.startsWith("data: ")) {
|
||||
@@ -640,15 +617,15 @@ async function streamingDashboard(prompt: string) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
```
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
### 🔁 Use Case 4: Task Polling Pattern
|
||||
|
||||
For long-running tasks, poll the task status instead of waiting synchronously.
|
||||
|
||||
```python
|
||||
За дълго изпълняващи се задачи, анкетирайте състоянието на задачата, вместо да чакате синхронно.```python
|
||||
import time
|
||||
|
||||
def poll_task(task_id: str, timeout: int = 60):
|
||||
@@ -678,75 +655,71 @@ def poll_task(task_id: str, timeout: int = 60):
|
||||
"params": {"taskId": task_id},
|
||||
})
|
||||
raise TimeoutError(f"Task {task_id} timed out after {timeout}s")
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Constant | Meaning |
|
||||
| ------ | ------------------------ | ---------------------------------------- |
|
||||
| -32700 | — | Parse error (invalid JSON) |
|
||||
| -32600 | `INVALID_REQUEST` | Invalid JSON-RPC request or unauthorized |
|
||||
| -32601 | `METHOD_NOT_FOUND` | Unknown method or skill |
|
||||
| -32602 | `INVALID_PARAMS` | Missing or invalid parameters |
|
||||
| -32603 | `INTERNAL_ERROR` | Skill execution failed |
|
||||
| -32001 | `TASK_NOT_FOUND` | Task ID not found |
|
||||
| -32002 | `TASK_ALREADY_COMPLETED` | Cannot modify a completed task |
|
||||
| -32003 | `UNAUTHORIZED` | Invalid or missing API key |
|
||||
| -32004 | `BUDGET_EXCEEDED` | Request exceeds configured budget |
|
||||
| -32005 | `PROVIDER_UNAVAILABLE` | No available providers |
|
||||
|
||||
---
|
||||
| Код | Постоянно | Значение |
|
||||
| ------ | ----------------------- | ------------------------------------------- | --- |
|
||||
| -32700 | — | Грешка при анализа (невалиден JSON) |
|
||||
| -32600 | `INVALID_REQUEST` | Невалидна JSON-RPC заявка или неупълномощен |
|
||||
| -32601 | `METHOD_NOT_FOUND` | Неизвестен метод или умение |
|
||||
| -32602 | `INVALID_PARAMS` | Липсващи или невалидни параметри |
|
||||
| -32603 | `ВЪТРЕШНА_ГРЕШКА` | Неуспешно изпълнение на умението |
|
||||
| -32001 | `ЗАДАЧА_НЕ_НАМЕРЕНА` | ID на задачата не е намерен |
|
||||
| -32002 | `ЗАДАЧА_ВЕЧЕ_ЗАВЪРШЕНА` | Не може да се промени завършена задача |
|
||||
| -32003 | `НЕУпълномощен` | Невалиден или липсващ API ключ |
|
||||
| -32004 | „БЮДЖЕТ_ПРЕВИШЕН“ | Заявката надвишава конфигурирания бюджет |
|
||||
| -32005 | `ДОСТАВЧИК_НЕДОСТЪПЕН` | Няма налични доставчици | --- |
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require a Bearer token via the `Authorization` header:
|
||||
|
||||
```
|
||||
Всички заявки `/a2a` изискват токен на носител чрез заглавката `Authorization`:```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
|
||||
```
|
||||
|
||||
If no API key is configured on the server (`OMNIROUTE_API_KEY` is empty), authentication is bypassed.
|
||||
|
||||
---
|
||||
Ако на сървъра не е конфигуриран API ключ („OMNIROUTE_API_KEY“ е празен), удостоверяването се заобикаля.---
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
|
||||
src/lib/a2a/
|
||||
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
|
||||
├── taskExecution.ts # Generic task executor with state management
|
||||
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
|
||||
├── routingLogger.ts # Routing decision logger (stats, history, retention)
|
||||
├── taskManager.ts # Task lifecycle (create/update/cancel/list), TTL, cleanup
|
||||
├── taskExecution.ts # Generic task executor with state management
|
||||
├── streaming.ts # SSE stream formatting, heartbeat, chunk/completion events
|
||||
├── routingLogger.ts # Routing decision logger (stats, history, retention)
|
||||
└── skills/
|
||||
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
|
||||
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
|
||||
├── smartRouting.ts # Smart routing skill (routes via /v1/chat/completions)
|
||||
└── quotaManagement.ts # Quota management skill (natural-language quota queries)
|
||||
|
||||
src/app/a2a/
|
||||
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
|
||||
└── route.ts # Next.js API route handler (JSON-RPC 2.0 dispatch)
|
||||
|
||||
open-sse/mcp-server/
|
||||
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
|
||||
└── schemas/a2a.ts # Zod schemas (AgentCard, Task, JSON-RPC, SSE events)
|
||||
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Comparison: MCP vs A2A
|
||||
|
||||
| Feature | MCP Server | A2A Server |
|
||||
| ----------------- | ---------------------------- | ------------------------------------------------- |
|
||||
| **Protocol** | Model Context Protocol | Agent-to-Agent Protocol v0.3 |
|
||||
| **Transport** | stdio / HTTP | HTTP (JSON-RPC 2.0) |
|
||||
| **Discovery** | Tool listing via MCP | `/.well-known/agent.json` |
|
||||
| **Granularity** | 16 individual tools | 2 high-level skills |
|
||||
| **Best for** | IDE agents (Cursor, VS Code) | Multi-agent systems (LangChain, CrewAI) |
|
||||
| **Streaming** | Not supported | SSE via `message/stream` |
|
||||
| **Task tracking** | No | Full lifecycle (submitted → completed) |
|
||||
| **Observability** | Audit log per tool call | Cost envelope + resilience trace + policy verdict |
|
||||
|
||||
---
|
||||
| Характеристика | MCP сървър | A2A сървър |
|
||||
| ----------------- | ---------------------------- | -------------------------------------------------- |
|
||||
|**Протокол**| Протокол на моделния контекст | Протокол от агент към агент v0.3 |
|
||||
|**Транспорт**| stdio / HTTP | HTTP (JSON-RPC 2.0) |
|
||||
|**Откритие**| Изброяване на инструменти чрез MCP | `/.well-known/agent.json` |
|
||||
|**Грануларност**| 16 отделни инструмента | 2 умения на високо ниво |
|
||||
|**Най-добро за**| IDE агенти (курсор, VS код) | Мултиагентни системи (LangChain, CrewAI) |
|
||||
|**Поточно предаване**| Не се поддържа | SSE чрез „съобщение/поток“ |
|
||||
|**Проследяване на задачи**| Не | Пълен жизнен цикъл (изпратен → завършен) |
|
||||
|**Наблюдаемост**| Журнал за проверка на извикване на инструмент | Разходен плик + проследяване на устойчивостта + присъда на политиката |---
|
||||
|
||||
## Лиценз
|
||||
|
||||
Part of [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — MIT License.
|
||||
Част от [OmniRoute](https://github.com/diegosouzapw/OmniRoute) — Лиценз на MIT.
|
||||
```
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,16 @@
|
||||
# Contributing to OmniRoute (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../CONTRIBUTING.md) · 🇪🇸 [es](../es/CONTRIBUTING.md) · 🇫🇷 [fr](../fr/CONTRIBUTING.md) · 🇩🇪 [de](../de/CONTRIBUTING.md) · 🇮🇹 [it](../it/CONTRIBUTING.md) · 🇷🇺 [ru](../ru/CONTRIBUTING.md) · 🇨🇳 [zh-CN](../zh-CN/CONTRIBUTING.md) · 🇯🇵 [ja](../ja/CONTRIBUTING.md) · 🇰🇷 [ko](../ko/CONTRIBUTING.md) · 🇸🇦 [ar](../ar/CONTRIBUTING.md) · 🇮🇳 [hi](../hi/CONTRIBUTING.md) · 🇮🇳 [in](../in/CONTRIBUTING.md) · 🇹🇭 [th](../th/CONTRIBUTING.md) · 🇻🇳 [vi](../vi/CONTRIBUTING.md) · 🇮🇩 [id](../id/CONTRIBUTING.md) · 🇲🇾 [ms](../ms/CONTRIBUTING.md) · 🇳🇱 [nl](../nl/CONTRIBUTING.md) · 🇵🇱 [pl](../pl/CONTRIBUTING.md) · 🇸🇪 [sv](../sv/CONTRIBUTING.md) · 🇳🇴 [no](../no/CONTRIBUTING.md) · 🇩🇰 [da](../da/CONTRIBUTING.md) · 🇫🇮 [fi](../fi/CONTRIBUTING.md) · 🇵🇹 [pt](../pt/CONTRIBUTING.md) · 🇷🇴 [ro](../ro/CONTRIBUTING.md) · 🇭🇺 [hu](../hu/CONTRIBUTING.md) · 🇧🇬 [bg](../bg/CONTRIBUTING.md) · 🇸🇰 [sk](../sk/CONTRIBUTING.md) · 🇺🇦 [uk-UA](../uk-UA/CONTRIBUTING.md) · 🇮🇱 [he](../he/CONTRIBUTING.md) · 🇵🇭 [phi](../phi/CONTRIBUTING.md) · 🇧🇷 [pt-BR](../pt-BR/CONTRIBUTING.md) · 🇨🇿 [cs](../cs/CONTRIBUTING.md) · 🇹🇷 [tr](../tr/CONTRIBUTING.md)
|
||||
|
||||
---
|
||||
|
||||
Thank you for your interest in contributing! This guide covers everything you need to get started.
|
||||
|
||||
---
|
||||
Děkujeme za váš zájem přispívat! Tato příručka obsahuje vše, co potřebujete, abyste mohli začít.---
|
||||
|
||||
## Development Setup
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- **Node.js** >= 18 < 24 (recommended: 22 LTS)
|
||||
- **npm** 10+
|
||||
- **Git**
|
||||
|
||||
### Clone & Install
|
||||
–**Node.js**>= 18 < 24 (doporučeno: 22 LTS) -**npm**10+ -**Git**### Clone & Install
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
@@ -35,28 +29,24 @@ echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
|
||||
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
|
||||
```
|
||||
|
||||
Key variables for development:
|
||||
Klíčové proměnné pro vývoj:
|
||||
|
||||
| Variable | Development Default | Description |
|
||||
| ---------------------- | ------------------------ | --------------------- |
|
||||
| `PORT` | `20128` | Server port |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Base URL for frontend |
|
||||
| `JWT_SECRET` | (generate above) | JWT signing secret |
|
||||
| `INITIAL_PASSWORD` | `CHANGEME` | First login password |
|
||||
| `APP_LOG_LEVEL` | `info` | Log verbosity level |
|
||||
| Proměnná | Vývoj Výchozí | Popis |
|
||||
| ---------------------- | ------------------------ | --------------------------- | ---------------------- |
|
||||
| "PORT" | "20128" | Port serveru |
|
||||
| `NEXT_PUBLIC_BASE_URL` | `http://localhost:20128` | Základní URL pro frontend |
|
||||
| `JWT_SECRET` | (vygenerovat výše) | Tajemství podpisu JWT |
|
||||
| `VÝCHOZÍ_HESLO` | "ZMĚNA" | První přihlašovací heslo |
|
||||
| `APP_LOG_LEVEL` | "informace" | Úroveň výřečnosti protokolu | ### Dashboard Settings |
|
||||
|
||||
### Dashboard Settings
|
||||
Ovládací panel poskytuje přepínače uživatelského rozhraní pro funkce, které lze také konfigurovat pomocí proměnných prostředí:
|
||||
|
||||
The dashboard provides UI toggles for features that can also be configured via environment variables:
|
||||
| Nastavení umístění | Přepnout | Popis |
|
||||
| -------------------- | ------------------------------ | ------------------------------------------ |
|
||||
| Nastavení → Upřesnit | Režim ladění | Povolit protokoly požadavků na ladění (UI) |
|
||||
| Nastavení → Obecné | Viditelnost postranního panelu | Zobrazit/skrýt sekce postranního panelu |
|
||||
|
||||
| Setting Location | Toggle | Description |
|
||||
| ------------------- | ------------------ | ------------------------------ |
|
||||
| Settings → Advanced | Debug Mode | Enable debug request logs (UI) |
|
||||
| Settings → General | Sidebar Visibility | Show/hide sidebar sections |
|
||||
|
||||
These settings are stored in the database and persist across restarts, overriding env var defaults when set.
|
||||
|
||||
### Running Locally
|
||||
Tato nastavení jsou uložena v databázi a přetrvávají po restartování, přičemž při nastavení přepisují výchozí hodnoty env var.### Running Locally
|
||||
|
||||
```bash
|
||||
# Development mode (hot reload)
|
||||
@@ -70,51 +60,44 @@ npm run start
|
||||
PORT=20128 NEXT_PUBLIC_BASE_URL=http://localhost:20128 npm run dev
|
||||
```
|
||||
|
||||
Default URLs:
|
||||
Výchozí adresy URL:
|
||||
|
||||
- **Dashboard**: `http://localhost:20128/dashboard`
|
||||
- **API**: `http://localhost:20128/v1`
|
||||
|
||||
---
|
||||
-**Dashboard**: `http://localhost:20128/dashboard` -**API**: `http://localhost:20128/v1`---
|
||||
|
||||
## Git Workflow
|
||||
|
||||
> ⚠️ **NEVER commit directly to `main`.** Always use feature branches.
|
||||
> ⚠️**NIKDY se nezavazujte přímo k `main`.**Vždy používejte větve funkcí.```bash
|
||||
> git checkout -b feat/your-feature-name
|
||||
|
||||
```bash
|
||||
git checkout -b feat/your-feature-name
|
||||
# ... make changes ...
|
||||
|
||||
git commit -m "feat: describe your change"
|
||||
git push -u origin feat/your-feature-name
|
||||
|
||||
# Open a Pull Request on GitHub
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### Branch Naming
|
||||
|
||||
| Prefix | Purpose |
|
||||
| ----------- | ------------------------- |
|
||||
| `feat/` | New features |
|
||||
| `fix/` | Bug fixes |
|
||||
| `refactor/` | Code restructuring |
|
||||
| `docs/` | Documentation changes |
|
||||
| `test/` | Test additions/fixes |
|
||||
| `chore/` | Tooling, CI, dependencies |
|
||||
| Předpona | Účel |
|
||||
| ----------- | -------------------------- |
|
||||
| `feat/` | Nové funkce |
|
||||
| `opravit/` | Opravy chyb |
|
||||
| `reaktor/` | Restrukturalizace kódu |
|
||||
| `docs/` | Změny dokumentace |
|
||||
| `test/` | Testovací doplňky/opravy |
|
||||
| `práce/` | Nástroje, CI, závislosti |### Commit Messages
|
||||
|
||||
### Commit Messages
|
||||
|
||||
Follow [Conventional Commits](https://www.conventionalcommits.org/):
|
||||
|
||||
```
|
||||
Sledujte [Conventional Commits](https://www.conventionalcommits.org/):```
|
||||
feat: add circuit breaker for provider calls
|
||||
fix: resolve JWT secret validation edge case
|
||||
docs: update SECURITY.md with PII protection
|
||||
test: add observability unit tests
|
||||
refactor(db): consolidate rate limit tables
|
||||
```
|
||||
````
|
||||
|
||||
Scopes: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `memory`, `skills`.
|
||||
|
||||
---
|
||||
Rozsahy: `db`, `sse`, `oauth`, `dashboard`, `api`, `cli`, `docker`, `ci`, `mcp`, `a2a`, `paměť`, `dovednosti`.---
|
||||
|
||||
## Running Tests
|
||||
|
||||
@@ -137,7 +120,7 @@ npm run test:protocols:e2e
|
||||
# Ecosystem compatibility tests
|
||||
npm run test:ecosystem
|
||||
|
||||
# Coverage (55% min statements/lines/functions; 60% branches)
|
||||
# Coverage (60% min statements/lines/functions/branches)
|
||||
npm run test:coverage
|
||||
npm run coverage:report
|
||||
|
||||
@@ -146,36 +129,37 @@ npm run lint
|
||||
npm run check
|
||||
```
|
||||
|
||||
Coverage notes:
|
||||
Poznámky k pokrytí:
|
||||
|
||||
- `npm run test:coverage` measures source coverage for the main unit test suite, excludes `tests/**`, and includes `open-sse/**`
|
||||
- `npm run coverage:report` prints the detailed file-by-file report from the latest coverage run
|
||||
- `npm run test:coverage:legacy` preserves the older metric for historical comparison
|
||||
- See `docs/COVERAGE_PLAN.md` for the phased coverage improvement roadmap
|
||||
- `npm run test:coverage` měří pokrytí zdroje pro hlavní testovací sadu jednotek, nezahrnuje `tests/**` a zahrnuje `open-sse/**`
|
||||
- Žádosti o stažení musí udržovat celkovou bránu pokrytí na**60 % nebo vyšší**pro příkazy, řádky, funkce a větve
|
||||
– Pokud PR změní produkční kód v `src/`, `open-sse/`, `electron/` nebo `bin/`, musí přidat nebo aktualizovat automatické testy ve stejném PR
|
||||
- `npm run coverage:report` vytiskne podrobnou zprávu soubor po souboru z posledního běhu pokrytí
|
||||
- `npm run test:coverage:legacy` zachovává starší metriku pro historické srovnání
|
||||
- Viz `docs/COVERAGE_PLAN.md` pro postupné zlepšování pokrytí### Pull Request Requirements
|
||||
|
||||
Current test status: **122 unit test files** covering:
|
||||
Před otevřením nebo sloučením PR:
|
||||
|
||||
- Provider translators and format conversion
|
||||
- Rate limiting, circuit breaker, and resilience
|
||||
- Semantic cache, idempotency, progress tracking
|
||||
- Database operations and schema (21 DB modules)
|
||||
- OAuth flows and authentication
|
||||
- API endpoint validation (Zod v4)
|
||||
- MCP server tools and scope enforcement
|
||||
- Memory and Skills systems
|
||||
- Spusťte `npm run test:unit`
|
||||
- Spusťte `npm run test:coverage`
|
||||
- Zajistěte, aby brána pokrytí zůstala na**60 %+**pro všechny metriky
|
||||
- Zahrnout změněné nebo přidané testovací soubory do popisu PR při změně výrobního kódu
|
||||
- Zkontrolujte výsledek SonarQube na PR, když jsou tajemství projektu nakonfigurována v CI
|
||||
|
||||
---
|
||||
Aktuální stav testu:**122 testovacích souborů jednotek**pokrývající:
|
||||
|
||||
- Poskytovatel překladatelů a konverze formátu
|
||||
- Omezení rychlosti, jistič a odolnost
|
||||
- Sémantická mezipaměť, idempotence, sledování pokroku
|
||||
- Databázové operace a schéma (21 DB modulů)
|
||||
- Toky OAuth a ověřování
|
||||
- Ověření koncového bodu API (Zod v4)
|
||||
- Serverové nástroje MCP a vynucení rozsahu
|
||||
- Systémy paměti a dovedností---
|
||||
|
||||
## Code Style
|
||||
|
||||
- **ESLint** — Run `npm run lint` before committing
|
||||
- **Prettier** — Auto-formatted via `lint-staged` on commit (2 spaces, semicolons, double quotes, 100 char width, es5 trailing commas)
|
||||
- **TypeScript** — All `src/` code uses `.ts`/`.tsx`; `open-sse/` uses `.ts`/`.js`; document with TSDoc (`@param`, `@returns`, `@throws`)
|
||||
- **No `eval()`** — ESLint enforces `no-eval`, `no-implied-eval`, `no-new-func`
|
||||
- **Zod validation** — Use Zod v4 schemas for all API input validation
|
||||
- **Naming**: Files = camelCase/kebab-case, components = PascalCase, constants = UPPER_SNAKE
|
||||
|
||||
---
|
||||
-**ESLint**— Před potvrzením spusťte příkaz `npm run lint` -**Hezčí**– Automatické formátování pomocí `lint-staged` při odevzdání (2 mezery, středníky, dvojité uvozovky, šířka 100 znaků, es5 koncové čárky) -**TypeScript**— Veškerý kód `src/` používá `.ts`/`.tsx`; `open-sse/` používá `.ts`/`.js`; dokument s TSDoc (`@param`, `@returns`, `@throws`) -**No `eval()`**— ESLint vynucuje `no-eval`, `no-implied-eval`, `no-new-func` -**Ověření Zod**– Používejte schémata Zod v4 pro ověřování všech vstupů API -**Pojmenování**: Soubory = camelCase/kebab-case, komponenty = PascalCase, konstanty = UPPER_SNAKE---
|
||||
|
||||
## Project Structure
|
||||
|
||||
@@ -244,56 +228,37 @@ docs/ # Documentation
|
||||
|
||||
### Step 1: Register Provider Constants
|
||||
|
||||
Add to `src/shared/constants/providers.ts` — Zod-validated at module load.
|
||||
Přidat do `src/shared/constants/providers.ts` — Zod-ověřeno při načtení modulu.### Step 2: Add Executor (if custom logic needed)
|
||||
|
||||
### Step 2: Add Executor (if custom logic needed)
|
||||
Vytvořte exekutor v `open-sse/executors/your-provider.ts` rozšiřující základní exekutor.### Step 3: Add Translator (if non-OpenAI format)
|
||||
|
||||
Create executor in `open-sse/executors/your-provider.ts` extending the base executor.
|
||||
Vytvořte překladače požadavků/odpovědí v `open-sse/translator/`.### Step 4: Add OAuth Config (if OAuth-based)
|
||||
|
||||
### Step 3: Add Translator (if non-OpenAI format)
|
||||
Přidejte přihlašovací údaje OAuth do `src/lib/oauth/constants/oauth.ts` a službu v `src/lib/oauth/services/`.### Step 5: Register Models
|
||||
|
||||
Create request/response translators in `open-sse/translator/`.
|
||||
Přidejte definice modelů do `open-sse/config/providerRegistry.ts`.### Step 6: Add Tests
|
||||
|
||||
### Step 4: Add OAuth Config (if OAuth-based)
|
||||
Napište testy jednotek v `tests/unit/` pokrývající minimálně:
|
||||
|
||||
Add OAuth credentials in `src/lib/oauth/constants/oauth.ts` and service in `src/lib/oauth/services/`.
|
||||
|
||||
### Step 5: Register Models
|
||||
|
||||
Add model definitions in `open-sse/config/providerRegistry.ts`.
|
||||
|
||||
### Step 6: Add Tests
|
||||
|
||||
Write unit tests in `tests/unit/` covering at minimum:
|
||||
|
||||
- Provider registration
|
||||
- Request/response translation
|
||||
- Error handling
|
||||
|
||||
---
|
||||
- Registrace poskytovatele
|
||||
- Překlad požadavku/odpovědi
|
||||
- Ošetření chyb---
|
||||
|
||||
## Pull Request Checklist
|
||||
|
||||
- [ ] Tests pass (`npm test`)
|
||||
- [ ] Linting passes (`npm run lint`)
|
||||
- [ ] Build succeeds (`npm run build`)
|
||||
- [ ] TypeScript types added for new public functions and interfaces
|
||||
- [ ] No hardcoded secrets or fallback values
|
||||
- [ ] All inputs validated with Zod schemas
|
||||
- [ ] CHANGELOG updated (if user-facing change)
|
||||
- [ ] Documentation updated (if applicable)
|
||||
|
||||
---
|
||||
- [ ] Testy úspěšné (`npm test`)
|
||||
- [ ] Linting passy (`npm run lint`)
|
||||
- [ ] Sestavení bylo úspěšné (`npm run build`)
|
||||
- [ ] Typy TypeScript přidány pro nové veřejné funkce a rozhraní
|
||||
- [ ] Žádná napevno zakódovaná tajemství nebo záložní hodnoty
|
||||
- [ ] Všechny vstupy ověřeny pomocí schémat Zod
|
||||
- [ ] CHANGELOG aktualizován (pokud se uživatel změní)
|
||||
- [ ] Aktualizace dokumentace (pokud existuje)---
|
||||
|
||||
## Releasing
|
||||
|
||||
Releases are managed via the `/generate-release` workflow. When a new GitHub Release is created, the package is **automatically published to npm** via GitHub Actions.
|
||||
|
||||
---
|
||||
Vydání se spravují pomocí pracovního postupu `/generate-release`. Když je vytvořeno nové vydání GitHubu, balíček je**automaticky publikován na npm**prostřednictvím akcí GitHub.---
|
||||
|
||||
## Getting Help
|
||||
|
||||
- **Architecture**: See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
||||
- **API Reference**: See [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md)
|
||||
- **Issues**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **ADRs**: See `docs/adr/` for architectural decision records
|
||||
-**Architektura**: Viz [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) -**Reference API**: Viz [`docs/API_REFERENCE.md`](docs/API_REFERENCE.md) -**Problémy**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues) -**ADR**: Viz `docs/adr/` pro záznamy architektonických rozhodnutí
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,161 +1,137 @@
|
||||
# Security Policy (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../SECURITY.md) · 🇪🇸 [es](../es/SECURITY.md) · 🇫🇷 [fr](../fr/SECURITY.md) · 🇩🇪 [de](../de/SECURITY.md) · 🇮🇹 [it](../it/SECURITY.md) · 🇷🇺 [ru](../ru/SECURITY.md) · 🇨🇳 [zh-CN](../zh-CN/SECURITY.md) · 🇯🇵 [ja](../ja/SECURITY.md) · 🇰🇷 [ko](../ko/SECURITY.md) · 🇸🇦 [ar](../ar/SECURITY.md) · 🇮🇳 [hi](../hi/SECURITY.md) · 🇮🇳 [in](../in/SECURITY.md) · 🇹🇭 [th](../th/SECURITY.md) · 🇻🇳 [vi](../vi/SECURITY.md) · 🇮🇩 [id](../id/SECURITY.md) · 🇲🇾 [ms](../ms/SECURITY.md) · 🇳🇱 [nl](../nl/SECURITY.md) · 🇵🇱 [pl](../pl/SECURITY.md) · 🇸🇪 [sv](../sv/SECURITY.md) · 🇳🇴 [no](../no/SECURITY.md) · 🇩🇰 [da](../da/SECURITY.md) · 🇫🇮 [fi](../fi/SECURITY.md) · 🇵🇹 [pt](../pt/SECURITY.md) · 🇷🇴 [ro](../ro/SECURITY.md) · 🇭🇺 [hu](../hu/SECURITY.md) · 🇧🇬 [bg](../bg/SECURITY.md) · 🇸🇰 [sk](../sk/SECURITY.md) · 🇺🇦 [uk-UA](../uk-UA/SECURITY.md) · 🇮🇱 [he](../he/SECURITY.md) · 🇵🇭 [phi](../phi/SECURITY.md) · 🇧🇷 [pt-BR](../pt-BR/SECURITY.md) · 🇨🇿 [cs](../cs/SECURITY.md) · 🇹🇷 [tr](../tr/SECURITY.md)
|
||||
|
||||
---
|
||||
|
||||
## Reporting Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability in OmniRoute, please report it responsibly:
|
||||
Pokud v OmniRoute objevíte bezpečnostní chybu, nahlaste ji prosím zodpovědně:
|
||||
|
||||
1. **DO NOT** open a public GitHub issue
|
||||
2. Use [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new)
|
||||
3. Include: description, reproduction steps, and potential impact
|
||||
1.**NEOTEVÍREJTE**veřejný problém GitHubu 2. Použijte [GitHub Security Advisories](https://github.com/diegosouzapw/OmniRoute/security/advisories/new) 3. Zahrňte: popis, kroky reprodukce a potenciální dopad## Response Timeline
|
||||
|
||||
## Response Timeline
|
||||
| Etapa | Cíl |
|
||||
| ------------------- | ---------------------------- | --------------------- |
|
||||
| Poděkování | 48 hodin |
|
||||
| Třídění a hodnocení | 5 pracovních dnů |
|
||||
| Vydání opravy | 14 pracovních dnů (kritické) | ## Supported Versions |
|
||||
|
||||
| Stage | Target |
|
||||
| ------------------- | --------------------------- |
|
||||
| Acknowledgment | 48 hours |
|
||||
| Triage & Assessment | 5 business days |
|
||||
| Patch Release | 14 business days (critical) |
|
||||
|
||||
## Supported Versions
|
||||
|
||||
| Version | Support Status |
|
||||
| ------- | -------------- |
|
||||
| 3.4.x | ✅ Active |
|
||||
| 3.0.x | ✅ Security |
|
||||
| < 3.0.0 | ❌ Unsupported |
|
||||
|
||||
---
|
||||
| Verze | Stav podpory |
|
||||
| ------- | ---------------- | --- |
|
||||
| 3.4.x | ✅ Aktivní |
|
||||
| 3.0.x | ✅ Zabezpečení |
|
||||
| < 3,0,0 | ❌ Nepodporováno | --- |
|
||||
|
||||
## Security Architecture
|
||||
|
||||
OmniRoute implements a multi-layered security model:
|
||||
|
||||
```
|
||||
OmniRoute implementuje vícevrstvý model zabezpečení:```
|
||||
Request → CORS → API Key Auth → Prompt Injection Guard → Input Sanitizer → Rate Limiter → Circuit Breaker → Provider
|
||||
```
|
||||
|
||||
`````
|
||||
|
||||
### 🔐 Authentication & Authorization
|
||||
|
||||
| Feature | Implementation |
|
||||
| -------------------- | ---------------------------------------------------------- |
|
||||
| **Dashboard Login** | Password-based auth with JWT tokens (HttpOnly cookies) |
|
||||
| **API Key Auth** | HMAC-signed keys with CRC validation |
|
||||
| **OAuth 2.0 + PKCE** | Secure provider auth (Claude, Codex, Gemini, Cursor, etc.) |
|
||||
| **Token Refresh** | Automatic OAuth token refresh before expiry |
|
||||
| **Secure Cookies** | `AUTH_COOKIE_SECURE=true` for HTTPS environments |
|
||||
| **MCP Scopes** | 10 granular scopes for MCP tool access control |
|
||||
| Funkce | Realizace |
|
||||
| --------------------- | ---------------------------------------------------------- |
|
||||
|**Přihlášení k panelu**| Ověřování na základě hesla s tokeny JWT (soubory cookie HttpOnly) |
|
||||
|**Ověření klíče API**| Klíče podepsané HMAC s ověřením CRC |
|
||||
|**OAuth 2.0 + PKCE**| Zabezpečené ověření poskytovatele (Claude, Codex, Gemini, Cursor atd.) |
|
||||
|**Obnovení tokenu**| Automatické obnovení tokenu OAuth před vypršením platnosti |
|
||||
|**Zabezpečené soubory cookie**| `AUTH_COOKIE_SECURE=true` pro prostředí HTTPS |
|
||||
|**Rozsahy MCP**| 10 granulárních rozsahů pro řízení přístupu k nástrojům MCP |### 🛡️ Encryption at Rest
|
||||
|
||||
### 🛡️ Encryption at Rest
|
||||
Všechna citlivá data uložená v SQLite jsou šifrována pomocí**AES-256-GCM**s odvozením šifrovacího klíče:
|
||||
|
||||
All sensitive data stored in SQLite is encrypted using **AES-256-GCM** with scrypt key derivation:
|
||||
|
||||
- API keys, access tokens, refresh tokens, and ID tokens
|
||||
- Versioned format: `enc:v1:<iv>:<ciphertext>:<authTag>`
|
||||
- Passthrough mode (plaintext) when `STORAGE_ENCRYPTION_KEY` is not set
|
||||
|
||||
```bash
|
||||
- Klíče API, přístupové tokeny, obnovovací tokeny a tokeny ID
|
||||
– Formát verze: `enc:v1:<iv>:<šifrový text>:<authTag>`
|
||||
- Režim průchodu (prostý text), když není nastaven `STORAGE_ENCRYPTION_KEY````bash
|
||||
# Generate encryption key:
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
`````
|
||||
|
||||
### 🧠 Prompt Injection Guard
|
||||
|
||||
Middleware that detects and blocks prompt injection attacks in LLM requests:
|
||||
Middleware, který detekuje a blokuje útoky rychlého vkládání v požadavcích LLM:
|
||||
|
||||
| Pattern Type | Severity | Example |
|
||||
| ------------------- | -------- | ---------------------------------------------- |
|
||||
| System Override | High | "ignore all previous instructions" |
|
||||
| Role Hijack | High | "you are now DAN, you can do anything" |
|
||||
| Delimiter Injection | Medium | Encoded separators to break context boundaries |
|
||||
| DAN/Jailbreak | High | Known jailbreak prompt patterns |
|
||||
| Instruction Leak | Medium | "show me your system prompt" |
|
||||
| Typ vzoru | Závažnost | Příklad |
|
||||
| --------------------- | --------- | ---------------------------------------------------- |
|
||||
| Přepsání systému | Vysoká | "ignorujte všechny předchozí pokyny" |
|
||||
| Role Hijack | Vysoká | "Nyní jsi DAN, můžeš dělat cokoliv" |
|
||||
| Vymezovač vstřikování | Střední | Kódované oddělovače pro porušení kontextových hranic |
|
||||
| DAN/Útěk z vězení | Vysoká | Známé vzory výzev k útěku z vězení |
|
||||
| Únik instrukce | Střední | "ukaž mi systémovou výzvu" |
|
||||
|
||||
Configure via dashboard (Settings → Security) or `.env`:
|
||||
|
||||
```env
|
||||
Konfigurace pomocí řídicího panelu (Nastavení → Zabezpečení) nebo `.env`:```env
|
||||
INPUT_SANITIZER_ENABLED=true
|
||||
INPUT_SANITIZER_MODE=block # warn | block | redact
|
||||
```
|
||||
INPUT_SANITIZER_MODE=block # warn | block | redact
|
||||
|
||||
````
|
||||
|
||||
### 🔒 PII Redaction
|
||||
|
||||
Automatic detection and optional redaction of personally identifiable information:
|
||||
Automatická detekce a volitelná redakce osobních údajů:
|
||||
|
||||
| PII Type | Pattern | Replacement |
|
||||
| ------------- | --------------------- | ------------------ |
|
||||
| Email | `user@domain.com` | `[EMAIL_REDACTED]` |
|
||||
| CPF (Brazil) | `123.456.789-00` | `[CPF_REDACTED]` |
|
||||
| CNPJ (Brazil) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
|
||||
| Credit Card | `4111-1111-1111-1111` | `[CC_REDACTED]` |
|
||||
| Phone | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
|
||||
| SSN (US) | `123-45-6789` | `[SSN_REDACTED]` |
|
||||
|
||||
```env
|
||||
| Typ PII | Vzor | Výměna |
|
||||
| ------------- | ---------------------- | ------------------- |
|
||||
| Email | `uživatel@domena.com` | `[EMAIL_REDACTED]` |
|
||||
| CPF (Brazílie) | `123 456 789-00` | `[CPF_REDACTED]` |
|
||||
| CNPJ (Brazílie) | `12.345.678/0001-00` | `[CNPJ_REDACTED]` |
|
||||
| Kreditní karta | `4111-1111-1111-1111` | `[CC_REDACTED]` |
|
||||
| Telefon | `+55 11 99999-9999` | `[PHONE_REDACTED]` |
|
||||
| SSN (USA) | `123-45-6789` | `[SSN_REDACTED]` |```env
|
||||
PII_REDACTION_ENABLED=true
|
||||
```
|
||||
````
|
||||
|
||||
### 🌐 Network Security
|
||||
|
||||
| Feature | Description |
|
||||
| ------------------------ | ---------------------------------------------------------------- |
|
||||
| **CORS** | Configurable origin control (`CORS_ORIGIN` env var, default `*`) |
|
||||
| **IP Filtering** | Allowlist/blocklist IP ranges in dashboard |
|
||||
| **Rate Limiting** | Per-provider rate limits with automatic backoff |
|
||||
| **Anti-Thundering Herd** | Mutex + per-connection locking prevents cascading 502s |
|
||||
| **TLS Fingerprint** | Browser-like TLS fingerprint spoofing to reduce bot detection |
|
||||
| **CLI Fingerprint** | Per-provider header/body ordering to match native CLI signatures |
|
||||
| Funkce | Popis |
|
||||
| ------------------------- | ------------------------------------------------------------------------------------ | -------------------------------- |
|
||||
| **CORS** | Konfigurovatelné řízení původu ('CORS_ORIGIN`env var, výchozí`\*`) |
|
||||
| **IP filtrování** | Seznam povolených/blokovaných rozsahů IP v řídicím panelu |
|
||||
| **Omezení sazby** | Limity sazeb na poskytovatele s automatickým stažením |
|
||||
| **Anti-Thundering Stádo** | Mutex + zamykání na připojení zabraňuje kaskádování 502s |
|
||||
| **TLS otisk prstu** | Falšování otisků prstů TLS podobné prohlížeči pro snížení detekce botů |
|
||||
| **CLI Fingerprint** | Uspořádání hlavičky/těla podle poskytovatele, aby odpovídalo nativním signaturám CLI | ### 🔌 Resilience & Availability |
|
||||
|
||||
### 🔌 Resilience & Availability
|
||||
| Funkce | Popis |
|
||||
| ------------------------ | ----------------------------------------------------------------------------- | ----------------- |
|
||||
| **Jistič** | 3stavový (Uzavřený → Otevřený → Polootevřený) na poskytovatele, SQLite-trvalý |
|
||||
| **Žádost o idempotenci** | 5sekundové okno pro odstranění duplicitních požadavků |
|
||||
| **Exponenciální ústup** | Automatické opakování s narůstajícím zpožděním |
|
||||
| **Health Dashboard** | Monitorování zdravotního stavu poskytovatele v reálném čase | ### 📋 Compliance |
|
||||
|
||||
| Feature | Description |
|
||||
| ----------------------- | ------------------------------------------------------------------ |
|
||||
| **Circuit Breaker** | 3-state (Closed → Open → Half-Open) per provider, SQLite-persisted |
|
||||
| **Request Idempotency** | 5-second dedup window for duplicate requests |
|
||||
| **Exponential Backoff** | Automatic retry with increasing delays |
|
||||
| **Health Dashboard** | Real-time provider health monitoring |
|
||||
|
||||
### 📋 Compliance
|
||||
|
||||
| Feature | Description |
|
||||
| ------------------ | ----------------------------------------------------------- |
|
||||
| **Log Retention** | Automatic cleanup after `CALL_LOG_RETENTION_DAYS` |
|
||||
| **No-Log Opt-out** | Per API key `noLog` flag disables request logging |
|
||||
| **Audit Log** | Administrative actions tracked in `audit_log` table |
|
||||
| **MCP Audit** | SQLite-backed audit logging for all MCP tool calls |
|
||||
| **Zod Validation** | All API inputs validated with Zod v4 schemas at module load |
|
||||
|
||||
---
|
||||
| Funkce | Popis |
|
||||
| ---------------------- | ----------------------------------------------------------------------- | --- |
|
||||
| **Uchování protokolu** | Automatické čištění po `CALL_LOG_RETENTION_DAYS` |
|
||||
| **No-Log Opt-out** | Příznak „noLog“ klíče API deaktivuje protokolování požadavků |
|
||||
| **Revizní protokol** | Administrativní akce sledované v tabulce `audit_log` |
|
||||
| **MCP Audit** | Protokolování auditu podporované SQLite pro všechna volání nástrojů MCP |
|
||||
| **Ověření zod** | Všechny vstupy API ověřeny pomocí schémat Zod v4 při zatížení modulu | --- |
|
||||
|
||||
## Required Environment Variables
|
||||
|
||||
All secrets must be set before starting the server. The server will **fail fast** if they are missing or weak.
|
||||
Všechna tajemství musí být nastavena před spuštěním serveru. Pokud chybí nebo jsou slabé, server**rychle selže**.```bash
|
||||
|
||||
```bash
|
||||
# REQUIRED — server will not start without these:
|
||||
|
||||
JWT_SECRET=$(openssl rand -base64 48) # min 32 chars
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
|
||||
API_KEY_SECRET=$(openssl rand -hex 32) # min 16 chars
|
||||
|
||||
# RECOMMENDED — enables encryption at rest:
|
||||
|
||||
STORAGE_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
||||
```
|
||||
|
||||
The server actively rejects known-weak values like `changeme`, `secret`, or `password`.
|
||||
````
|
||||
|
||||
---
|
||||
Server aktivně odmítá známé slabé hodnoty, jako je „changeme“, „secret“ nebo „password“.---
|
||||
|
||||
## Docker Security
|
||||
|
||||
- Use non-root user in production
|
||||
- Mount secrets as read-only volumes
|
||||
- Never copy `.env` files into Docker images
|
||||
- Use `.dockerignore` to exclude sensitive files
|
||||
- Set `AUTH_COOKIE_SECURE=true` when behind HTTPS
|
||||
|
||||
```bash
|
||||
- V produkci použijte uživatele bez oprávnění root
|
||||
- Připojte tajné klíče jako svazky pouze pro čtení
|
||||
- Nikdy nekopírujte soubory `.env` do obrazů Dockeru
|
||||
- Použijte `.dockerignore` k vyloučení citlivých souborů
|
||||
- Nastavte `AUTH_COOKIE_SECURE=true`, když je za HTTPS```bash
|
||||
docker run -d \
|
||||
--name omniroute \
|
||||
--restart unless-stopped \
|
||||
@@ -166,14 +142,14 @@ docker run -d \
|
||||
-e API_KEY_SECRET="$(openssl rand -hex 32)" \
|
||||
-e STORAGE_ENCRYPTION_KEY="$(openssl rand -hex 32)" \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- Run `npm audit` regularly
|
||||
- Keep dependencies updated
|
||||
- The project uses `husky` + `lint-staged` for pre-commit checks
|
||||
- CI pipeline runs ESLint security rules on every push
|
||||
- Provider constants validated at module load via Zod (`src/shared/validation/providerSchema.ts`)
|
||||
- Pravidelně spouštějte `npm audit`
|
||||
- Udržujte závislosti aktualizované
|
||||
- Projekt používá `husky` + `lint-staged` pro kontroly před potvrzením
|
||||
- CI kanál spouští bezpečnostní pravidla ESLint při každém push
|
||||
- Konstanty poskytovatele ověřené při načtení modulu přes Zod (`src/shared/validation/providerSchema.ts`)
|
||||
|
||||
@@ -1,40 +1,31 @@
|
||||
# OmniRoute A2A Server Documentation (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/A2A-SERVER.md) · 🇪🇸 [es](../../es/docs/A2A-SERVER.md) · 🇫🇷 [fr](../../fr/docs/A2A-SERVER.md) · 🇩🇪 [de](../../de/docs/A2A-SERVER.md) · 🇮🇹 [it](../../it/docs/A2A-SERVER.md) · 🇷🇺 [ru](../../ru/docs/A2A-SERVER.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/A2A-SERVER.md) · 🇯🇵 [ja](../../ja/docs/A2A-SERVER.md) · 🇰🇷 [ko](../../ko/docs/A2A-SERVER.md) · 🇸🇦 [ar](../../ar/docs/A2A-SERVER.md) · 🇮🇳 [hi](../../hi/docs/A2A-SERVER.md) · 🇮🇳 [in](../../in/docs/A2A-SERVER.md) · 🇹🇭 [th](../../th/docs/A2A-SERVER.md) · 🇻🇳 [vi](../../vi/docs/A2A-SERVER.md) · 🇮🇩 [id](../../id/docs/A2A-SERVER.md) · 🇲🇾 [ms](../../ms/docs/A2A-SERVER.md) · 🇳🇱 [nl](../../nl/docs/A2A-SERVER.md) · 🇵🇱 [pl](../../pl/docs/A2A-SERVER.md) · 🇸🇪 [sv](../../sv/docs/A2A-SERVER.md) · 🇳🇴 [no](../../no/docs/A2A-SERVER.md) · 🇩🇰 [da](../../da/docs/A2A-SERVER.md) · 🇫🇮 [fi](../../fi/docs/A2A-SERVER.md) · 🇵🇹 [pt](../../pt/docs/A2A-SERVER.md) · 🇷🇴 [ro](../../ro/docs/A2A-SERVER.md) · 🇭🇺 [hu](../../hu/docs/A2A-SERVER.md) · 🇧🇬 [bg](../../bg/docs/A2A-SERVER.md) · 🇸🇰 [sk](../../sk/docs/A2A-SERVER.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/A2A-SERVER.md) · 🇮🇱 [he](../../he/docs/A2A-SERVER.md) · 🇵🇭 [phi](../../phi/docs/A2A-SERVER.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/A2A-SERVER.md) · 🇨🇿 [cs](../../cs/docs/A2A-SERVER.md) · 🇹🇷 [tr](../../tr/docs/A2A-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
|
||||
## Agent Discovery
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute jako inteligentní směrovací agent## Agent Discovery
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
|
||||
---
|
||||
Vrátí kartu agenta popisující možnosti, dovednosti a požadavky na ověření OmniRoute.---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Všechny požadavky `/a2a` vyžadují klíč API prostřednictvím záhlaví `Authorization`:```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
````
|
||||
|
||||
---
|
||||
Pokud na serveru není nakonfigurován žádný klíč API, ověřování je vynecháno.---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
Odešle zprávu dovednosti a čeká na kompletní odpověď.```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
@@ -48,34 +39,31 @@ curl -X POST http://localhost:20128/a2a \
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**Odpověď:**```json
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"result": {
|
||||
"task": { "id": "uuid", "state": "completed" },
|
||||
"artifacts": [{ "type": "text", "content": "..." }],
|
||||
"metadata": {
|
||||
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
|
||||
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
|
||||
"resilience_trace": [
|
||||
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
|
||||
],
|
||||
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
|
||||
}
|
||||
}
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"result": {
|
||||
"task": { "id": "uuid", "state": "completed" },
|
||||
"artifacts": [{ "type": "text", "content": "..." }],
|
||||
"metadata": {
|
||||
"routing_explanation": "Selected claude-sonnet via provider \"anthropic\" (latency: 1200ms, cost: $0.003)",
|
||||
"cost_envelope": { "estimated": 0.005, "actual": 0.003, "currency": "USD" },
|
||||
"resilience_trace": [
|
||||
{ "event": "primary_selected", "provider": "anthropic", "timestamp": "..." }
|
||||
],
|
||||
"policy_verdict": { "allowed": true, "reason": "within budget and quota limits" }
|
||||
}
|
||||
```
|
||||
}
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
### `message/stream` — SSE Streaming
|
||||
|
||||
Same as `message/send` but returns Server-Sent Events for real-time streaming.
|
||||
|
||||
```bash
|
||||
Stejné jako `zpráva/odeslat`, ale vrací události odeslané serverem pro streamování v reálném čase.```bash
|
||||
curl -N -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
@@ -88,17 +76,16 @@ curl -N -X POST http://localhost:20128/a2a \
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
````
|
||||
|
||||
**SSE Events:**
|
||||
|
||||
```
|
||||
**Události SSE:**```
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"working"},"chunk":{"type":"text","content":"..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"jsonrpc":"2.0","method":"message/stream","params":{"task":{"id":"...","state":"completed"},"metadata":{...}}}
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
### `tasks/get` — Query Task Status
|
||||
|
||||
@@ -107,7 +94,7 @@ curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{"jsonrpc":"2.0","id":"2","method":"tasks/get","params":{"taskId":"TASK_UUID"}}'
|
||||
```
|
||||
````
|
||||
|
||||
### `tasks/cancel` — Cancel a Task
|
||||
|
||||
@@ -122,12 +109,10 @@ curl -X POST http://localhost:20128/a2a \
|
||||
|
||||
## Available Skills
|
||||
|
||||
| Skill | Description |
|
||||
| :----------------- | :------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `smart-routing` | Routes prompts through OmniRoute's intelligent pipeline. Returns response with routing explanation, cost, and resilience trace. |
|
||||
| `quota-management` | Answers natural-language queries about provider quotas, suggests free combos, and provides quota rankings. |
|
||||
|
||||
---
|
||||
| Dovednost | Popis |
|
||||
| :----------------- | :---------------------------------------------------------------------------------------------------------------------------------- | --- |
|
||||
| "chytré směrování" | Výzvy Routes prostřednictvím inteligentního potrubí OmniRoute. Vrátí odpověď s vysvětlením směrování, cenou a trasováním odolnosti. |
|
||||
| "správa kvót" | Odpovídá na dotazy v přirozeném jazyce o kvótách poskytovatelů, navrhuje bezplatná komba a poskytuje hodnocení kvót. | --- |
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
@@ -137,23 +122,19 @@ submitted → working → completed
|
||||
→ cancelled
|
||||
```
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
|
||||
---
|
||||
- Platnost úkolů vyprší po 5 minutách (lze konfigurovat)
|
||||
- Stavy terminálu: "dokončeno", "neúspěšné", "zrušeno".
|
||||
- Protokol událostí sleduje každý přechod stavu---
|
||||
|
||||
## Error Codes
|
||||
|
||||
| Code | Meaning |
|
||||
| :----- | :----------------------------- |
|
||||
| -32700 | Parse error (invalid JSON) |
|
||||
| -32600 | Invalid request / Unauthorized |
|
||||
| -32601 | Method or skill not found |
|
||||
| -32602 | Invalid params |
|
||||
| -32603 | Internal error |
|
||||
|
||||
---
|
||||
| Kód | Význam |
|
||||
| :----- | :------------------------------- | --- |
|
||||
| -32700 | Chyba analýzy (neplatný JSON) |
|
||||
| -32600 | Neplatný požadavek / neoprávněný |
|
||||
| -32601 | Metoda nebo dovednost nenalezena |
|
||||
| -32602 | Neplatné parametry |
|
||||
| -32603 | Vnitřní chyba | --- |
|
||||
|
||||
## Integration Examples
|
||||
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
# API Reference (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/API_REFERENCE.md) · 🇪🇸 [es](../../es/docs/API_REFERENCE.md) · 🇫🇷 [fr](../../fr/docs/API_REFERENCE.md) · 🇩🇪 [de](../../de/docs/API_REFERENCE.md) · 🇮🇹 [it](../../it/docs/API_REFERENCE.md) · 🇷🇺 [ru](../../ru/docs/API_REFERENCE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/API_REFERENCE.md) · 🇯🇵 [ja](../../ja/docs/API_REFERENCE.md) · 🇰🇷 [ko](../../ko/docs/API_REFERENCE.md) · 🇸🇦 [ar](../../ar/docs/API_REFERENCE.md) · 🇮🇳 [hi](../../hi/docs/API_REFERENCE.md) · 🇮🇳 [in](../../in/docs/API_REFERENCE.md) · 🇹🇭 [th](../../th/docs/API_REFERENCE.md) · 🇻🇳 [vi](../../vi/docs/API_REFERENCE.md) · 🇮🇩 [id](../../id/docs/API_REFERENCE.md) · 🇲🇾 [ms](../../ms/docs/API_REFERENCE.md) · 🇳🇱 [nl](../../nl/docs/API_REFERENCE.md) · 🇵🇱 [pl](../../pl/docs/API_REFERENCE.md) · 🇸🇪 [sv](../../sv/docs/API_REFERENCE.md) · 🇳🇴 [no](../../no/docs/API_REFERENCE.md) · 🇩🇰 [da](../../da/docs/API_REFERENCE.md) · 🇫🇮 [fi](../../fi/docs/API_REFERENCE.md) · 🇵🇹 [pt](../../pt/docs/API_REFERENCE.md) · 🇷🇴 [ro](../../ro/docs/API_REFERENCE.md) · 🇭🇺 [hu](../../hu/docs/API_REFERENCE.md) · 🇧🇬 [bg](../../bg/docs/API_REFERENCE.md) · 🇸🇰 [sk](../../sk/docs/API_REFERENCE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/API_REFERENCE.md) · 🇮🇱 [he](../../he/docs/API_REFERENCE.md) · 🇵🇭 [phi](../../phi/docs/API_REFERENCE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/API_REFERENCE.md) · 🇨🇿 [cs](../../cs/docs/API_REFERENCE.md) · 🇹🇷 [tr](../../tr/docs/API_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
---
|
||||
Kompletní reference pro všechny koncové body rozhraní API OmniRoute.---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Dokončení chatu](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
- [Image Generation](#image-generation)
|
||||
- [List Models](#list-models)
|
||||
- [Compatibility Endpoints](#compatibility-endpoints)
|
||||
- [Semantic Cache](#semantic-cache)
|
||||
- [Generování obrázků](#image-generation)
|
||||
- [Seznam modelů](#list-models)
|
||||
- [Koncové body kompatibility](#compatibility-endpoints)
|
||||
- [Sémantická mezipaměť](#sémantická mezipaměť)
|
||||
- [Dashboard & Management](#dashboard--management)
|
||||
- [Request Processing](#request-processing)
|
||||
- [Authentication](#authentication)
|
||||
|
||||
---
|
||||
- [Zpracování požadavku](#request-processing)
|
||||
- [Authentication](#authentication)---
|
||||
|
||||
## Chat Completions
|
||||
|
||||
@@ -40,22 +36,20 @@ Content-Type: application/json
|
||||
|
||||
### Custom Headers
|
||||
|
||||
| Header | Direction | Description |
|
||||
| ------------------------ | --------- | ------------------------------------------------ |
|
||||
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
|
||||
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
|
||||
| `X-Session-Id` | Request | Sticky session key for external session affinity |
|
||||
| `x_session_id` | Request | Underscore variant also accepted (direct HTTP) |
|
||||
| `Idempotency-Key` | Request | Dedup key (5s window) |
|
||||
| `X-Request-Id` | Request | Alternative dedup key |
|
||||
| `X-OmniRoute-Cache` | Response | `HIT` or `MISS` (non-streaming) |
|
||||
| `X-OmniRoute-Idempotent` | Response | `true` if deduplicated |
|
||||
| `X-OmniRoute-Progress` | Response | `enabled` if progress tracking on |
|
||||
| `X-OmniRoute-Session-Id` | Response | Effective session ID used by OmniRoute |
|
||||
| Záhlaví | Směr | Popis |
|
||||
| ------------------------ | ------- | ------------------------------------------------ | -------------------- |
|
||||
| `X-OmniRoute-No-Cache` | Žádost | Chcete-li obejít mezipaměť | , nastavte na `true` |
|
||||
| `X-OmniRoute-Progress` | Žádost | Nastavte na `true` pro události průběhu |
|
||||
| `X-Session-Id` | Žádost | Sticky session key pro externí afinitu relace |
|
||||
| `x_session_id` | Žádost | Přijímá se také varianta podtržítka (přímé HTTP) |
|
||||
| "Idempotency-key" | Žádost | Deup klíč (okno 5s) |
|
||||
| `X-Request-Id` | Žádost | Alternativní dedup klíč |
|
||||
| `X-OmniRoute-Cache` | Odpověď | „HIT“ nebo „MISS“ (bez streamování) |
|
||||
| "X-OmniRoute-Idempotent" | Odpověď | "pravda", pokud je deduplikováno |
|
||||
| `X-OmniRoute-Progress` | Odpověď | "povoleno", pokud je sledování pokroku na |
|
||||
| `X-OmniRoute-Session-Id` | Odpověď | Efektivní ID relace používané OmniRoute |
|
||||
|
||||
> Nginx note: if you rely on underscore headers (for example `x_session_id`), enable `underscores_in_headers on;`.
|
||||
|
||||
---
|
||||
> Poznámka Nginx: pokud spoléháte na hlavičky podtržení (například `x_session_id`), povolte `underscores_in_headers on;`.---
|
||||
|
||||
## Embeddings
|
||||
|
||||
@@ -70,12 +64,13 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
Dostupní poskytovatelé: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.```bash
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -91,14 +86,15 @@ Content-Type: application/json
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
Dostupní poskytovatelé: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.```bash
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -109,26 +105,24 @@ GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Compatibility Endpoints
|
||||
|
||||
| Method | Path | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Anthropic |
|
||||
| POST | `/v1/responses` | OpenAI Responses |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| GET | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Anthropic |
|
||||
| GET | `/v1beta/models` | Gemini |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
|
||||
### Dedicated Provider Routes
|
||||
| Metoda | Cesta | Formát |
|
||||
| --------- | --------------------------- | ---------------------- | ----------------------------- |
|
||||
| PŘÍSPĚVEK | `/v1/chat/completions` | OpenAI |
|
||||
| PŘÍSPĚVEK | `/v1/messages` | Antropický |
|
||||
| PŘÍSPĚVEK | `/v1/responses` | Odezvy OpenAI |
|
||||
| PŘÍSPĚVEK | `/v1/embeddings` | OpenAI |
|
||||
| PŘÍSPĚVEK | `/v1/images/generations` | OpenAI |
|
||||
| ZÍSKEJTE | `/v1/modely` | OpenAI |
|
||||
| PŘÍSPĚVEK | `/v1/messages/count_tokens` | Antropický |
|
||||
| ZÍSKEJTE | `/v1beta/modely` | Blíženci |
|
||||
| PŘÍSPĚVEK | `/v1beta/modely/{...cesta}` | Blíženci generujíObsah |
|
||||
| PŘÍSPĚVEK | `/v1/api/chat` | Ollama | ### Dedicated Provider Routes |
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
@@ -136,9 +130,7 @@ POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
---
|
||||
Pokud chybí předpona poskytovatele, je automaticky přidána. Neodpovídající modely vrátí „400“.---
|
||||
|
||||
## Semantic Cache
|
||||
|
||||
@@ -150,22 +142,21 @@ GET /api/cache/stats
|
||||
DELETE /api/cache/stats
|
||||
```
|
||||
|
||||
Response example:
|
||||
|
||||
```json
|
||||
Příklad odpovědi:```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
```
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -173,165 +164,129 @@ Response example:
|
||||
|
||||
### Authentication
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------------- | ------- | --------------------- |
|
||||
| `/api/auth/login` | POST | Login |
|
||||
| `/api/auth/logout` | POST | Logout |
|
||||
| `/api/settings/require-login` | GET/PUT | Toggle login required |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ------------------------------ | ------- | ---------------------- |
|
||||
| `/api/auth/login` | PŘÍSPĚVEK | Přihlásit |
|
||||
| `/api/auth/logout` | PŘÍSPĚVEK | Odhlášení |
|
||||
| `/api/settings/require-login` | GET/PUT | Přepnout vyžadováno přihlášení |### Provider Management
|
||||
|
||||
### Provider Management
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ----------------------------- | ---------------- | ------------------------- |
|
||||
| `/api/poskytovatelé` | ZÍSKAT/POSLAT | Seznam / vytvoření poskytovatelů |
|
||||
| `/api/providers/[id]` | GET/PUT/DELETE | Spravovat poskytovatele |
|
||||
| `/api/providers/[id]/test` | PŘÍSPĚVEK | Test připojení poskytovatele |
|
||||
| `/api/providers/[id]/models` | ZÍSKEJTE | Seznam modelů poskytovatelů |
|
||||
| `/api/providers/validate` | PŘÍSPĚVEK | Ověřit konfiguraci poskytovatele |
|
||||
| `/api/nodes-poskytovatele*` | Různé | Správa uzlu poskytovatele |
|
||||
| `/api/provider-models` | ZÍSKAT/POSLAT/SMAZAT | Vlastní modely |### OAuth Flows
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------------- | --------------- | ------------------------ |
|
||||
| `/api/providers` | GET/POST | List / create providers |
|
||||
| `/api/providers/[id]` | GET/PUT/DELETE | Manage a provider |
|
||||
| `/api/providers/[id]/test` | POST | Test provider connection |
|
||||
| `/api/providers/[id]/models` | GET | List provider models |
|
||||
| `/api/providers/validate` | POST | Validate provider config |
|
||||
| `/api/provider-nodes*` | Various | Provider node management |
|
||||
| `/api/provider-models` | GET/POST/DELETE | Custom models |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| --------------------------------- | ------- | ------------------------ |
|
||||
| `/api/oauth/[poskytovatel]/[akce]` | Různé | OAuth specifické pro poskytovatele |### Routing & Config
|
||||
|
||||
### OAuth Flows
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------------- | -------- | ------------------------------ |
|
||||
| `/api/models/alias` | ZÍSKAT/POSLAT | Modelové aliasy |
|
||||
| `/api/models/catalog` | ZÍSKEJTE | Všechny modely podle poskytovatele + typu |
|
||||
| `/api/combos*` | Různé | Combo management |
|
||||
| `/api/keys*` | Různé | Správa klíčů API |
|
||||
| `/api/pricing` | ZÍSKEJTE | Cena modelu |### Usage & Analytics
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------------- | ------- | ----------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------------------- | ------ | --------------------- |
|
||||
| `/api/usage/history` | ZÍSKEJTE | Historie použití |
|
||||
| `/api/usage/logs` | ZÍSKEJTE | Protokoly použití |
|
||||
| `/api/usage/request-logs` | ZÍSKEJTE | Protokoly na úrovni požadavku |
|
||||
| `/api/usage/[connectionId]` | ZÍSKEJTE | Využití na připojení |### Settings
|
||||
|
||||
### Routing & Config
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| -------------------------------- | ------------- | ----------------------- |
|
||||
| `/api/settings` | GET/PUT/PATCH | Obecná nastavení |
|
||||
| `/api/settings/proxy` | GET/PUT | Konfigurace síťového proxy |
|
||||
| `/api/settings/proxy/test` | PŘÍSPĚVEK | Test připojení proxy |
|
||||
| `/api/settings/ip-filter` | GET/PUT | Seznam povolených/blokovaných IP adres |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Rozpočet s odůvodněním |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Globální systémová výzva |### Monitoring
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------- | -------- | ----------------------------- |
|
||||
| `/api/models/alias` | GET/POST | Model aliases |
|
||||
| `/api/models/catalog` | GET | All models by provider + type |
|
||||
| `/api/combos*` | Various | Combo management |
|
||||
| `/api/keys*` | Various | API key management |
|
||||
| `/api/pricing` | GET | Model pricing |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ------------------------- | ---------- | --------------------------------------------------------------------------------------------------
|
||||
| `/api/sessions` | ZÍSKEJTE | Sledování aktivní relace |
|
||||
| `/api/rate-limits` | ZÍSKEJTE | Limity sazeb za účet |
|
||||
| `/api/monitoring/health` | ZÍSKEJTE | Kontrola stavu + souhrn poskytovatele (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
|
||||
| `/api/cache/stats` | ZÍSKAT/SMAZAT | Statistiky mezipaměti / vymazat |### Backup & Export/Import
|
||||
|
||||
### Usage & Analytics
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------------------- | ------ | ---------------------------------------- |
|
||||
| `/api/db-backups` | ZÍSKEJTE | Seznam dostupných záloh |
|
||||
| `/api/db-backups` | PUT | Vytvořte ruční zálohu |
|
||||
| `/api/db-backups` | PŘÍSPĚVEK | Obnovit z konkrétní zálohy |
|
||||
| `/api/db-backups/export` | ZÍSKEJTE | Stáhnout databázi jako soubor .sqlite |
|
||||
| `/api/db-backups/import` | PŘÍSPĚVEK | Nahrajte soubor .sqlite pro nahrazení databáze |
|
||||
| `/api/db-backups/exportAll` | ZÍSKEJTE | Stáhnout plnou zálohu jako archiv .tar.gz |### Cloud Sync
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | -------------------- |
|
||||
| `/api/usage/history` | GET | Usage history |
|
||||
| `/api/usage/logs` | GET | Usage logs |
|
||||
| `/api/usage/request-logs` | GET | Request-level logs |
|
||||
| `/api/usage/[connectionId]` | GET | Per-connection usage |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ----------------------- | ------- | ---------------------- |
|
||||
| `/api/sync/cloud` | Různé | Operace synchronizace s cloudem |
|
||||
| `/api/sync/initialize` | PŘÍSPĚVEK | Inicializovat synchronizaci |
|
||||
| `/api/cloud/*` | Různé | Správa cloudu |### Tunnels
|
||||
|
||||
### Settings
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| --------------------------- | ------ | ------------------------------------------------------------------------ |
|
||||
| `/api/tunely/cloudflared` | ZÍSKEJTE | Přečtěte si stav instalace/běhu Cloudflare Quick Tunnel pro řídicí panel |
|
||||
| `/api/tunely/cloudflared` | PŘÍSPĚVEK | Povolit nebo zakázat Cloudflare Quick Tunnel (`action=enable/disable`) |### CLI Tools
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------------- | ------------- | ---------------------- |
|
||||
| `/api/settings` | GET/PUT/PATCH | General settings |
|
||||
| `/api/settings/proxy` | GET/PUT | Network proxy config |
|
||||
| `/api/settings/proxy/test` | POST | Test proxy connection |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------------------------- | ------ | -------------------- |
|
||||
| `/api/cli-tools/claude-settings` | ZÍSKEJTE | Claude CLI status |
|
||||
| `/api/cli-tools/codex-settings` | ZÍSKEJTE | Status Codex CLI |
|
||||
| `/api/cli-tools/droid-settings` | ZÍSKEJTE | Stav CLI Droid |
|
||||
| `/api/cli-tools/openclaw-settings` | ZÍSKEJTE | Stav OpenClaw CLI |
|
||||
| `/api/cli-tools/runtime/[toolId]` | ZÍSKEJTE | Generic CLI runtime |
|
||||
|
||||
### Monitoring
|
||||
Odpovědi CLI zahrnují: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, ,reason`.### ACP Agents
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------ | ---------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| `/api/sessions` | GET | Active session tracking |
|
||||
| `/api/rate-limits` | GET | Per-account rate limits |
|
||||
| `/api/monitoring/health` | GET | Health check + provider summary (`catalogCount`, `configuredCount`, `activeCount`, `monitoredCount`) |
|
||||
| `/api/cache/stats` | GET/DELETE | Cache stats / clear |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ------------------ | ------ | --------------------------------------------------------- |
|
||||
| `/api/acp/agents` | ZÍSKEJTE | Vypsat všechny detekované agenty (vestavěné + vlastní) se stavem |
|
||||
| `/api/acp/agents` | PŘÍSPĚVEK | Přidejte vlastního agenta nebo obnovte mezipaměť detekce |
|
||||
| `/api/acp/agents` | VYMAZAT | Odeberte vlastního agenta pomocí parametru dotazu `id` |
|
||||
|
||||
### Backup & Export/Import
|
||||
Odpověď GET zahrnuje „agenty[]“ (id, název, binární, verze, nainstalovaný, protokol, isCustom) a „summary“ (celkem, nainstalovaný, nenalezen, vestavěný, vlastní).### Resilience & Rate Limits
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | --------------------------------------- |
|
||||
| `/api/db-backups` | GET | List available backups |
|
||||
| `/api/db-backups` | PUT | Create a manual backup |
|
||||
| `/api/db-backups` | POST | Restore from a specific backup |
|
||||
| `/api/db-backups/export` | GET | Download database as .sqlite file |
|
||||
| `/api/db-backups/import` | POST | Upload .sqlite file to replace database |
|
||||
| `/api/db-backups/exportAll` | GET | Download full backup as .tar.gz archive |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ------------------------ | --------- | -------------------------------- |
|
||||
| `/api/resilience` | GET/PATCH | Získat/aktualizovat profily odolnosti |
|
||||
| `/api/resilience/reset` | PŘÍSPĚVEK | Resetujte jističe |
|
||||
| `/api/rate-limits` | ZÍSKEJTE | Stav limitu sazby na účet |
|
||||
| `/api/rate-limit` | ZÍSKEJTE | Konfigurace globálního limitu rychlosti |### Evals
|
||||
|
||||
### Cloud Sync
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ------------ | -------- | ---------------------------------- |
|
||||
| `/api/evals` | ZÍSKAT/POSLAT | Vypsat vyhodnocovací sady / spustit vyhodnocení |### Policies
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------- | ------- | --------------------- |
|
||||
| `/api/sync/cloud` | Various | Cloud sync operations |
|
||||
| `/api/sync/initialize` | POST | Initialize sync |
|
||||
| `/api/cloud/*` | Various | Cloud management |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------- | ---------------- | ------------------------ |
|
||||
| `/api/policies` | ZÍSKAT/POSLAT/SMAZAT | Spravovat zásady směrování |### Compliance
|
||||
|
||||
### Tunnels
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------------------- | ------ | ------------------------------ |
|
||||
| `/api/compliance/audit-log` | ZÍSKEJTE | Záznam auditu shody (poslední N) |### v1beta (Gemini-Compatible)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | ----------------------------------------------------------------------- |
|
||||
| `/api/tunnels/cloudflared` | GET | Read Cloudflare Quick Tunnel install/runtime status for the dashboard |
|
||||
| `/api/tunnels/cloudflared` | POST | Enable or disable the Cloudflare Quick Tunnel (`action=enable/disable`) |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| --------------------------- | ------ | ---------------------------------- |
|
||||
| `/v1beta/modely` | ZÍSKEJTE | Seznam modelů ve formátu Gemini |
|
||||
| `/v1beta/modely/{...cesta}` | PŘÍSPĚVEK | Koncový bod Gemini `generateContent` |
|
||||
|
||||
### CLI Tools
|
||||
Tyto koncové body odrážejí formát API Gemini pro klienty, kteří očekávají nativní kompatibilitu Gemini SDK.### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------------------- | ------ | ------------------- |
|
||||
| `/api/cli-tools/claude-settings` | GET | Claude CLI status |
|
||||
| `/api/cli-tools/codex-settings` | GET | Codex CLI status |
|
||||
| `/api/cli-tools/droid-settings` | GET | Droid CLI status |
|
||||
| `/api/cli-tools/openclaw-settings` | GET | OpenClaw CLI status |
|
||||
| `/api/cli-tools/runtime/[toolId]` | GET | Generic CLI runtime |
|
||||
| Koncový bod | Metoda | Popis |
|
||||
| ---------------- | ------ | ----------------------------------------------------- |
|
||||
| `/api/init` | ZÍSKEJTE | Kontrola inicializace aplikace (používá se při prvním spuštění) |
|
||||
| `/api/tags` | ZÍSKEJTE | Modelové značky kompatibilní s Ollama (pro klienty Ollama) |
|
||||
| `/api/restart` | PŘÍSPĚVEK | Spustit elegantní restart serveru |
|
||||
| `/api/shutdown` | PŘÍSPĚVEK | Spustit elegantní vypnutí serveru |
|
||||
|
||||
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### ACP Agents
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------- | ------ | -------------------------------------------------------- |
|
||||
| `/api/acp/agents` | GET | List all detected agents (built-in + custom) with status |
|
||||
| `/api/acp/agents` | POST | Add custom agent or refresh detection cache |
|
||||
| `/api/acp/agents` | DELETE | Remove a custom agent by `id` query param |
|
||||
|
||||
GET response includes `agents[]` (id, name, binary, version, installed, protocol, isCustom) and `summary` (total, installed, notFound, builtIn, custom).
|
||||
|
||||
### Resilience & Rate Limits
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------- | --------- | ------------------------------- |
|
||||
| `/api/resilience` | GET/PATCH | Get/update resilience profiles |
|
||||
| `/api/resilience/reset` | POST | Reset circuit breakers |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
| `/api/rate-limit` | GET | Global rate limit configuration |
|
||||
|
||||
### Evals
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| ------------ | -------- | --------------------------------- |
|
||||
| `/api/evals` | GET/POST | List eval suites / run evaluation |
|
||||
|
||||
### Policies
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
|
||||
|
||||
### Compliance
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
|
||||
|
||||
### v1beta (Gemini-Compatible)
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | --------------------------------- |
|
||||
| `/v1beta/models` | GET | List models in Gemini format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
|
||||
|
||||
These endpoints mirror Gemini's API format for clients that expect native Gemini SDK compatibility.
|
||||
|
||||
### Internal / System APIs
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | ------ | ---------------------------------------------------- |
|
||||
| `/api/init` | GET | Application initialization check (used on first run) |
|
||||
| `/api/tags` | GET | Ollama-compatible model tags (for Ollama clients) |
|
||||
| `/api/restart` | POST | Trigger graceful server restart |
|
||||
| `/api/shutdown` | POST | Trigger graceful server shutdown |
|
||||
|
||||
> **Note:** These endpoints are used internally by the system or for Ollama client compatibility. They are not typically called by end users.
|
||||
|
||||
---
|
||||
>**Poznámka:**Tyto koncové body jsou používány interně systémem nebo kvůli kompatibilitě klienta Ollama. Obvykle je nevolají koncoví uživatelé.---
|
||||
|
||||
## Audio Transcription
|
||||
|
||||
@@ -339,69 +294,63 @@ These endpoints mirror Gemini's API format for clients that expect native Gemini
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
````
|
||||
|
||||
Transcribe audio files using Deepgram or AssemblyAI.
|
||||
Přepisujte zvukové soubory pomocí Deepgram nebo AssemblyAI.
|
||||
|
||||
**Request:**
|
||||
|
||||
```bash
|
||||
**Žádost:**```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"
|
||||
```
|
||||
-H "Authorization: Bearer your-api-key" \
|
||||
-F "file=@recording.mp3" \
|
||||
-F "model=deepgram/nova-3"
|
||||
|
||||
**Response:**
|
||||
````
|
||||
|
||||
```json
|
||||
**Odpověď:**```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
**Podporovaní poskytovatelé:**`deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
**Podporované formáty:**`mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.---
|
||||
|
||||
## Ollama Compatibility
|
||||
|
||||
For clients that use Ollama's API format:
|
||||
Pro klienty, kteří používají formát Ollama's API:```bash
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Requests are automatically translated between Ollama and internal formats.
|
||||
````
|
||||
|
||||
---
|
||||
Požadavky jsou automaticky překládány mezi Ollama a interními formáty.---
|
||||
|
||||
## Telemetry
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
````
|
||||
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
**Odpověď:**```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
```
|
||||
}
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -420,7 +369,7 @@ Content-Type: application/json
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -443,23 +392,21 @@ Content-Type: application/json
|
||||
|
||||
## Request Processing
|
||||
|
||||
1. Client sends request to `/v1/*`
|
||||
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
|
||||
3. Model is resolved (direct provider/model or alias/combo)
|
||||
4. Credentials selected from local DB with account availability filtering
|
||||
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
|
||||
6. Provider executor sends upstream request
|
||||
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
|
||||
8. Usage/logging recorded
|
||||
9. Fallback applies on errors according to combo rules
|
||||
1. Klient odešle požadavek na `/v1/*`
|
||||
2. Volání obslužného programu trasy `handleChat`, `handleEmbedding`, `handleAudioTranscription` nebo `handleImageGeneration`
|
||||
3. Model je vyřešen (přímý poskytovatel/model nebo alias/kombo)
|
||||
4. Přihlašovací údaje vybrané z místní databáze s filtrováním dostupnosti účtu
|
||||
5. Pro chat: `handleChatCore` — detekce formátu, překlad, kontrola mezipaměti, kontrola idempotence
|
||||
6. Exekutor poskytovatele odešle upstream požadavek
|
||||
7. Odpověď přeložená zpět do formátu klienta (chat) nebo vrácena tak, jak je (vložení/obrázky/audio)
|
||||
8. Zaznamenáno používání/protokolování
|
||||
9. Záložní funkce se vztahuje na chyby podle pravidel kombinace
|
||||
|
||||
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
Úplný odkaz na architekturu: [`ARCHITECTURE.md`](ARCHITECTURE.md)---
|
||||
|
||||
## Authentication
|
||||
|
||||
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
|
||||
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
|
||||
- `requireLogin` toggleable via `/api/settings/require-login`
|
||||
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
|
||||
- Trasy řídicího panelu (`/dashboard/*`) používají soubor cookie `auth_token`
|
||||
- Přihlášení používá uložený hash hesla; přechod na `INITIAL_PASSWORD`
|
||||
- `requireLogin` přepínatelné přes `/api/settings/require-login`
|
||||
- trasy `/v1/*` volitelně vyžadují klíč rozhraní API nosiče, když je `REQUIRE_API_KEY=true`
|
||||
|
||||
@@ -1,93 +1,83 @@
|
||||
# OmniRoute Architecture (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇮🇳 [in](../../in/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/ARCHITECTURE.md) · 🇪🇸 [es](../../es/docs/ARCHITECTURE.md) · 🇫🇷 [fr](../../fr/docs/ARCHITECTURE.md) · 🇩🇪 [de](../../de/docs/ARCHITECTURE.md) · 🇮🇹 [it](../../it/docs/ARCHITECTURE.md) · 🇷🇺 [ru](../../ru/docs/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/ARCHITECTURE.md) · 🇯🇵 [ja](../../ja/docs/ARCHITECTURE.md) · 🇰🇷 [ko](../../ko/docs/ARCHITECTURE.md) · 🇸🇦 [ar](../../ar/docs/ARCHITECTURE.md) · 🇮🇳 [hi](../../hi/docs/ARCHITECTURE.md) · 🇮🇳 [in](../../in/docs/ARCHITECTURE.md) · 🇹🇭 [th](../../th/docs/ARCHITECTURE.md) · 🇻🇳 [vi](../../vi/docs/ARCHITECTURE.md) · 🇮🇩 [id](../../id/docs/ARCHITECTURE.md) · 🇲🇾 [ms](../../ms/docs/ARCHITECTURE.md) · 🇳🇱 [nl](../../nl/docs/ARCHITECTURE.md) · 🇵🇱 [pl](../../pl/docs/ARCHITECTURE.md) · 🇸🇪 [sv](../../sv/docs/ARCHITECTURE.md) · 🇳🇴 [no](../../no/docs/ARCHITECTURE.md) · 🇩🇰 [da](../../da/docs/ARCHITECTURE.md) · 🇫🇮 [fi](../../fi/docs/ARCHITECTURE.md) · 🇵🇹 [pt](../../pt/docs/ARCHITECTURE.md) · 🇷🇴 [ro](../../ro/docs/ARCHITECTURE.md) · 🇭🇺 [hu](../../hu/docs/ARCHITECTURE.md) · 🇧🇬 [bg](../../bg/docs/ARCHITECTURE.md) · 🇸🇰 [sk](../../sk/docs/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/ARCHITECTURE.md) · 🇮🇱 [he](../../he/docs/ARCHITECTURE.md) · 🇵🇭 [phi](../../phi/docs/ARCHITECTURE.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/ARCHITECTURE.md) · 🇨🇿 [cs](../../cs/docs/ARCHITECTURE.md) · 🇹🇷 [tr](../../tr/docs/ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
_Last updated: 2026-03-28_
|
||||
_Poslední aktualizace: 28.03.2026_## Executive Summary
|
||||
|
||||
## Executive Summary
|
||||
OmniRoute je místní AI směrovací brána a řídicí panel postavený na Next.js.
|
||||
Poskytuje jeden koncový bod kompatibilní s OpenAI (`/v1/*`) a směruje provoz přes několik upstreamových poskytovatelů s překladem, nouzovým obnovením, obnovením tokenu a sledováním využití.
|
||||
|
||||
OmniRoute is a local AI routing gateway and dashboard built on Next.js.
|
||||
It provides a single OpenAI-compatible endpoint (`/v1/*`) and routes traffic across multiple upstream providers with translation, fallback, token refresh, and usage tracking.
|
||||
Základní schopnosti:
|
||||
|
||||
Core capabilities:
|
||||
- OpenAI kompatibilní povrch API pro CLI/nástroje (28 poskytovatelů)
|
||||
- Překlad požadavku/odpovědi mezi formáty poskytovatelů
|
||||
- Záložní kombinace modelů (sekvence více modelů)
|
||||
– Záloha na úrovni účtu (více účtů na poskytovatele)
|
||||
- Správa připojení poskytovatele OAuth + API klíče
|
||||
- Generování vkládání pomocí `/v1/embeddings` (6 poskytovatelů, 9 modelů)
|
||||
- Generování obrázků pomocí `/v1/images/generations` (4 poskytovatelé, 9 modelů)
|
||||
- Myslete na analýzu značek (`<think>...</think>`) pro modely uvažování
|
||||
- Dezinfekce odezvy pro přísnou kompatibilitu OpenAI SDK
|
||||
- Normalizace rolí (vývojář→systém, systém→uživatel) pro kompatibilitu mezi poskytovateli
|
||||
- Konverze strukturovaného výstupu (json_schema → Gemini responseSchema)
|
||||
- Místní perzistence pro poskytovatele, klíče, aliasy, komba, nastavení, ceny
|
||||
- Sledování využití/nákladů a protokolování požadavků
|
||||
- Volitelná cloudová synchronizace pro synchronizaci mezi více zařízeními/stavy
|
||||
- Seznam povolených/blokovaných IP pro řízení přístupu k API
|
||||
- Myslet na správu rozpočtu (průchozí/automatické/vlastní/adaptivní)
|
||||
- Okamžité vstřikování globálního systému
|
||||
- Sledování relací a snímání otisků prstů
|
||||
- Rozšířené omezení sazeb na účet pomocí profilů specifických pro poskytovatele
|
||||
- Vzor jističe pro odolnost poskytovatele
|
||||
- Ochrana stáda proti hromu s mutexovým zamykáním
|
||||
- Mezipaměť deduplikace požadavků na základě podpisu
|
||||
- Doménová vrstva: dostupnost modelu, nákladová pravidla, záložní politika, politika uzamčení
|
||||
- Perzistence stavu domény (mezipaměť pro zápis SQLite pro záložní, rozpočty, uzamčení, jističe)
|
||||
- Modul zásad pro centralizované vyhodnocování požadavků (uzamčení → rozpočet → záložní)
|
||||
- Vyžádejte si telemetrii s agregací latence p50/p95/p99
|
||||
- ID korelace (X-Request-Id) pro end-to-end trasování
|
||||
- Protokolování auditu shody s odhlášením podle klíče API
|
||||
- Eval rámec pro zajištění kvality LLM
|
||||
- Řídicí panel Resilience UI se stavem jističe v reálném čase
|
||||
- Modulární poskytovatelé OAuth (12 jednotlivých modulů pod `src/lib/oauth/providers/`)
|
||||
|
||||
- OpenAI-compatible API surface for CLI/tools (28 providers)
|
||||
- Request/response translation across provider formats
|
||||
- Model combo fallback (multi-model sequence)
|
||||
- Account-level fallback (multi-account per provider)
|
||||
- OAuth + API-key provider connection management
|
||||
- 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
|
||||
- IP allowlist/blocklist for API access control
|
||||
- Thinking budget management (passthrough/auto/custom/adaptive)
|
||||
- Global system prompt injection
|
||||
- Session tracking and fingerprinting
|
||||
- Per-account enhanced rate limiting with provider-specific profiles
|
||||
- Circuit breaker pattern for provider resilience
|
||||
- Anti-thundering herd protection with mutex locking
|
||||
- Signature-based request deduplication cache
|
||||
- Domain layer: model availability, cost rules, fallback policy, lockout policy
|
||||
- Domain state persistence (SQLite write-through cache for fallbacks, budgets, lockouts, circuit breakers)
|
||||
- Policy engine for centralized request evaluation (lockout → budget → fallback)
|
||||
- Request telemetry with p50/p95/p99 latency aggregation
|
||||
- Correlation ID (X-Request-Id) for end-to-end tracing
|
||||
- Compliance audit logging with opt-out per API key
|
||||
- Eval framework for LLM quality assurance
|
||||
- Resilience UI dashboard with real-time circuit breaker status
|
||||
- Modular OAuth providers (12 individual modules under `src/lib/oauth/providers/`)
|
||||
Primární runtime model:
|
||||
|
||||
Primary runtime model:
|
||||
|
||||
- Next.js app routes under `src/app/api/*` implement both dashboard APIs and compatibility APIs
|
||||
- A shared SSE/routing core in `src/sse/*` + `open-sse/*` handles provider execution, translation, streaming, fallback, and usage
|
||||
|
||||
## Scope and Boundaries
|
||||
- Trasy aplikací Next.js pod `src/app/api/*` implementují jak rozhraní API řídicího panelu, tak rozhraní API pro kompatibilitu
|
||||
- Sdílené jádro SSE/směrování v `src/sse/*` + `open-sse/*` se stará o provádění poskytovatele, překlad, streamování, zálohování a používání## Scope and Boundaries
|
||||
|
||||
### In Scope
|
||||
|
||||
- Local gateway runtime
|
||||
- Dashboard management APIs
|
||||
- Provider authentication and token refresh
|
||||
- Request translation and SSE streaming
|
||||
- Local state + usage persistence
|
||||
- Optional cloud sync orchestration
|
||||
- Runtime místní brány
|
||||
- Rozhraní API pro správu řídicích panelů
|
||||
- Ověření poskytovatele a obnovení tokenu
|
||||
- Vyžádejte si překlad a streamování SSE
|
||||
- Místní stav + perzistence používání
|
||||
- Volitelná orchestrace synchronizace s cloudem### Out of Scope
|
||||
|
||||
### Out of Scope
|
||||
- Implementace cloudové služby za `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Poskytovatel SLA/řídící rovina mimo místní proces
|
||||
- Samotné externí binární soubory CLI (Claude CLI, Codex CLI atd.)## Dashboard Surface (Current)
|
||||
|
||||
- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Provider SLA/control plane outside local process
|
||||
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
|
||||
Hlavní stránky pod `src/app/(dashboard)/dashboard/`:
|
||||
|
||||
## Dashboard Surface (Current)
|
||||
|
||||
Main pages under `src/app/(dashboard)/dashboard/`:
|
||||
|
||||
- `/dashboard` — quick start + provider overview
|
||||
- `/dashboard/endpoint` — endpoint proxy + MCP + A2A + API endpoint tabs
|
||||
- `/dashboard/providers` — provider connections and credentials
|
||||
- `/dashboard/combos` — combo strategies, templates, model routing rules
|
||||
- `/dashboard/costs` — cost aggregation and pricing visibility
|
||||
- `/dashboard/analytics` — usage analytics and evaluations
|
||||
- `/dashboard/limits` — quota/rate controls
|
||||
- `/dashboard/cli-tools` — CLI onboarding, runtime detection, config generation
|
||||
- `/dashboard/agents` — detected ACP agents + custom agent registration
|
||||
- `/dashboard/media` — image/video/music playground
|
||||
- `/dashboard/search-tools` — search provider testing and history
|
||||
- `/dashboard/health` — uptime, circuit breakers, rate limits
|
||||
- `/dashboard/logs` — request/proxy/audit/console logs
|
||||
- `/dashboard/settings` — system settings tabs (general, routing, combo defaults, etc.)
|
||||
- `/dashboard/api-manager` — API key lifecycle and model permissions
|
||||
|
||||
## High-Level System Context
|
||||
- `/dashboard` — rychlý start + přehled poskytovatele
|
||||
- `/dashboard/endpoint` — proxy koncového bodu + MCP + A2A + karty koncového bodu API
|
||||
- `/dashboard/providers` — připojení a přihlašovací údaje poskytovatele
|
||||
- `/dashboard/combos` — kombo strategie, šablony, pravidla směrování modelů
|
||||
- `/dashboard/costs` — agregace nákladů a viditelnost cen
|
||||
- `/dashboard/analytics` — analýzy a vyhodnocení využití
|
||||
- `/dashboard/limits` — kontroly kvót/sazeb
|
||||
- `/dashboard/cli-tools` — CLI onboarding, runtime detekce, generování konfigurace
|
||||
- `/dashboard/agents` — detekovaní agenti AKT + vlastní registrace agenta
|
||||
- `/dashboard/media` — hřiště pro obrázky/video/hudbu
|
||||
- `/dashboard/search-tools` — testování a historie poskytovatelů vyhledávání
|
||||
- `/dashboard/health` — doba provozuschopnosti, jističe, limity sazeb
|
||||
- `/dashboard/logs` — protokoly požadavku/proxy/audit/konzole
|
||||
- `/dashboard/settings` — karty nastavení systému (obecné, směrování, výchozí kombinace atd.)
|
||||
- `/dashboard/api-manager` — životní cyklus klíče API a oprávnění k modelu## High-Level System Context
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -139,149 +129,139 @@ flowchart LR
|
||||
|
||||
## 1) API and Routing Layer (Next.js App Routes)
|
||||
|
||||
Main directories:
|
||||
Hlavní adresáře:
|
||||
|
||||
- `src/app/api/v1/*` and `src/app/api/v1beta/*` for compatibility APIs
|
||||
- `src/app/api/*` for management/configuration APIs
|
||||
- Next rewrites in `next.config.mjs` map `/v1/*` to `/api/v1/*`
|
||||
- `src/app/api/v1/*` a `src/app/api/v1beta/*` pro rozhraní API pro kompatibilitu
|
||||
- `src/app/api/*` pro správu/konfiguraci API
|
||||
- Další přepíše mapu `next.config.mjs` `/v1/*` na `/api/v1/*`
|
||||
|
||||
Important compatibility routes:
|
||||
Důležité cesty kompatibility:
|
||||
|
||||
- `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` — includes custom models with `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — embedding generation (6 providers)
|
||||
- `src/app/api/v1/images/generations/route.ts` — image generation (4+ providers incl. Antigravity/Nebius)
|
||||
- `src/app/api/v1/models/route.ts` — zahrnuje vlastní modely s `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — generování vložení (6 poskytovatelů)
|
||||
- `src/app/api/v1/images/generations/route.ts` — generování obrázků (4+ poskytovatelé včetně Antigravity/Nebius)
|
||||
- `src/app/api/v1/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — dedicated per-provider chat
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — dedicated per-provider embeddings
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — dedicated per-provider images
|
||||
– `src/app/api/v1/providers/[poskytovatel]/chat/completions/route.ts` – vyhrazený chat pro jednotlivé poskytovatele
|
||||
– `src/app/api/v1/providers/[poskytovatel]/embeddings/route.ts` – vyhrazená vložení pro jednotlivé poskytovatele
|
||||
- `src/app/api/v1/providers/[poskytovatel]/images/generations/route.ts` – vyhrazené obrázky pro jednotlivé poskytovatele
|
||||
- `src/app/api/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
- `src/app/api/v1beta/models/[...cesta]/route.ts`
|
||||
|
||||
Management domains:
|
||||
Domény správy:
|
||||
|
||||
- Auth/settings: `src/app/api/auth/*`, `src/app/api/settings/*`
|
||||
- Providers/connections: `src/app/api/providers*`
|
||||
- Provider nodes: `src/app/api/provider-nodes*`
|
||||
- Custom models: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Model catalog: `src/app/api/models/route.ts` (GET)
|
||||
- Proxy config: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- Poskytovatelé/připojení: `src/app/api/providers*`
|
||||
- Uzly poskytovatele: `src/app/api/provider-nodes*`
|
||||
- Vlastní modely: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Katalog modelů: `src/app/api/models/route.ts` (GET)
|
||||
- Konfigurace proxy: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- Keys/aliases/combos/pricing: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Usage: `src/app/api/usage/*`
|
||||
- Klíče/aliasy/komba/cena: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Použití: `src/app/api/usage/*`
|
||||
- Sync/cloud: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
||||
- CLI tooling helpers: `src/app/api/cli-tools/*`
|
||||
- IP filter: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Pomocníci nástrojů CLI: `src/app/api/cli-tools/*`
|
||||
- IP filtr: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Thinking budget: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- System prompt: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Sessions: `src/app/api/sessions` (GET)
|
||||
- Rate limits: `src/app/api/rate-limits` (GET)
|
||||
- Resilience: `src/app/api/resilience` (GET/PATCH) — provider profiles, circuit breaker, rate limit state
|
||||
- Resilience reset: `src/app/api/resilience/reset` (POST) — reset breakers + cooldowns
|
||||
- Cache stats: `src/app/api/cache/stats` (GET/DELETE)
|
||||
- Model availability: `src/app/api/models/availability` (GET/POST)
|
||||
- Telemetry: `src/app/api/telemetry/summary` (GET)
|
||||
- Budget: `src/app/api/usage/budget` (GET/POST)
|
||||
- Fallback chains: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Compliance audit: `src/app/api/compliance/audit-log` (GET)
|
||||
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Policies: `src/app/api/policies` (GET/POST)
|
||||
- Systémová výzva: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Relace: `src/app/api/sessions` (GET)
|
||||
- Sazbové limity: `src/app/api/rate-limits` (GET)
|
||||
- Odolnost: `src/app/api/resilience` (GET/PATCH) — profily poskytovatelů, jistič, stav omezení rychlosti
|
||||
- Resetování odolnosti: `src/app/api/resilience/reset` (POST) — resetujte jističe + cooldowny
|
||||
- Statistiky mezipaměti: `src/app/api/cache/stats` (GET/DELETE)
|
||||
- Dostupnost modelu: `src/app/api/models/availability` (GET/POST)
|
||||
- Telemetrie: `src/app/api/telemetry/summary` (GET)
|
||||
– Rozpočet: `src/app/api/usage/budget` (GET/POST)
|
||||
- Záložní řetězce: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Audit souladu: `src/app/api/compliance/audit-log` (GET)
|
||||
- Hodnoty: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Zásady: `src/app/api/policies` (GET/POST)## 2) SSE + Translation Core
|
||||
|
||||
## 2) SSE + Translation Core
|
||||
Hlavní průtokové moduly:
|
||||
|
||||
Main flow modules:
|
||||
- Záznam: `src/sse/handlers/chat.ts`
|
||||
- Základní orchestrace: `open-sse/handlers/chatCore.ts`
|
||||
- Spouštěcí adaptéry poskytovatele: `open-sse/executors/*`
|
||||
- Detekce formátu/konfigurace poskytovatele: `open-sse/services/provider.ts`
|
||||
- Parse/resolve modelu: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
||||
- Logika záložního účtu: `open-sse/services/accountFallback.ts`
|
||||
- Registr překladů: `open-sse/translator/index.ts`
|
||||
- Transformace streamu: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
||||
- Extrakce/normalizace použití: `open-sse/utils/usageTracking.ts`
|
||||
- Analyzátor značek Think: `open-sse/utils/thinkTagParser.ts`
|
||||
- Obsluha vkládání: `open-sse/handlers/embeddings.ts`
|
||||
- Registr poskytovatele vkládání: `open-sse/config/embeddingRegistry.ts`
|
||||
- Ovladač generování obrázků: `open-sse/handlers/imageGeneration.ts`
|
||||
- Registr poskytovatele obrázků: `open-sse/config/imageRegistry.ts`
|
||||
- Dezinfekce odezvy: `open-sse/handlers/responseSanitizer.ts`
|
||||
- Normalizace rolí: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
- Entry: `src/sse/handlers/chat.ts`
|
||||
- Core orchestration: `open-sse/handlers/chatCore.ts`
|
||||
- Provider execution adapters: `open-sse/executors/*`
|
||||
- Format detection/provider config: `open-sse/services/provider.ts`
|
||||
- Model parse/resolve: `src/sse/services/model.ts`, `open-sse/services/model.ts`
|
||||
- Account fallback logic: `open-sse/services/accountFallback.ts`
|
||||
- Translation registry: `open-sse/translator/index.ts`
|
||||
- Stream transformations: `open-sse/utils/stream.ts`, `open-sse/utils/streamHandler.ts`
|
||||
- Usage extraction/normalization: `open-sse/utils/usageTracking.ts`
|
||||
- Think tag parser: `open-sse/utils/thinkTagParser.ts`
|
||||
- Embedding handler: `open-sse/handlers/embeddings.ts`
|
||||
- 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`
|
||||
Služby (obchodní logika):
|
||||
|
||||
Services (business logic):
|
||||
|
||||
- Account selection/scoring: `open-sse/services/accountSelector.ts`
|
||||
- Context lifecycle management: `open-sse/services/contextManager.ts`
|
||||
- IP filter enforcement: `open-sse/services/ipFilter.ts`
|
||||
- Session tracking: `open-sse/services/sessionManager.ts`
|
||||
- Request deduplication: `open-sse/services/signatureCache.ts`
|
||||
- System prompt injection: `open-sse/services/systemPrompt.ts`
|
||||
- Výběr účtu/bodování: `open-sse/services/accountSelector.ts`
|
||||
- Kontextová správa životního cyklu: `open-sse/services/contextManager.ts`
|
||||
- Vynucení filtru IP: `open-sse/services/ipFilter.ts`
|
||||
- Sledování relací: `open-sse/services/sessionManager.ts`
|
||||
- Žádost o deduplikaci: `open-sse/services/signatureCache.ts`
|
||||
- Vložení příkazu systému: `open-sse/services/systemPrompt.ts`
|
||||
- Thinking budget management: `open-sse/services/thinkingBudget.ts`
|
||||
- Wildcard model routing: `open-sse/services/wildcardRouter.ts`
|
||||
- Rate limit management: `open-sse/services/rateLimitManager.ts`
|
||||
- Circuit breaker: `open-sse/services/circuitBreaker.ts`
|
||||
- Směrování modelu se zástupnými znaky: `open-sse/services/wildcardRouter.ts`
|
||||
- Správa limitu sazby: `open-sse/services/rateLimitManager.ts`
|
||||
- Jistič: `open-sse/services/circuitBreaker.ts`
|
||||
|
||||
Domain layer modules:
|
||||
Moduly vrstvy domény:
|
||||
|
||||
- Model availability: `src/lib/domain/modelAvailability.ts`
|
||||
- Cost rules/budgets: `src/lib/domain/costRules.ts`
|
||||
- Fallback policy: `src/lib/domain/fallbackPolicy.ts`
|
||||
- Dostupnost modelu: `src/lib/domain/modelAvailability.ts`
|
||||
- Pravidla/rozpočty nákladů: `src/lib/domain/costRules.ts`
|
||||
- Záložní zásady: `src/lib/domain/fallbackPolicy.ts`
|
||||
- Combo resolver: `src/lib/domain/comboResolver.ts`
|
||||
- Lockout policy: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Policy engine: `src/domain/policyEngine.ts` — centralized lockout → budget → fallback evaluation
|
||||
- Error codes catalog: `src/lib/domain/errorCodes.ts`
|
||||
- Request ID: `src/lib/domain/requestId.ts`
|
||||
- Fetch timeout: `src/lib/domain/fetchTimeout.ts`
|
||||
- Request telemetry: `src/lib/domain/requestTelemetry.ts`
|
||||
- Compliance/audit: `src/lib/domain/compliance/index.ts`
|
||||
- Zásady uzamčení: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Modul zásad: `src/domain/policyEngine.ts` — centralizované uzamčení → rozpočet → záložní vyhodnocení
|
||||
- Katalog chybových kódů: `src/lib/domain/errorCodes.ts`
|
||||
- ID požadavku: `src/lib/domain/requestId.ts`
|
||||
- Časový limit načtení: `src/lib/domain/fetchTimeout.ts`
|
||||
- Žádost o telemetrii: `src/lib/domain/requestTelemetry.ts`
|
||||
- Soulad/audit: `src/lib/domain/compliance/index.ts`
|
||||
- Eval runner: `src/lib/domain/evalRunner.ts`
|
||||
- Domain state persistence: `src/lib/db/domainState.ts` — SQLite CRUD for fallback chains, budgets, cost history, lockout state, circuit breakers
|
||||
- Trvalost stavu domény: `src/lib/db/domainState.ts` — SQLite CRUD pro záložní řetězce, rozpočty, historii nákladů, stav uzamčení, jističe
|
||||
|
||||
OAuth provider modules (12 individual files under `src/lib/oauth/providers/`):
|
||||
Moduly poskytovatele OAuth (12 samostatných souborů pod `src/lib/oauth/providers/`):
|
||||
|
||||
- Registry index: `src/lib/oauth/providers/index.ts`
|
||||
- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules
|
||||
- Index registru: `src/lib/oauth/providers/index.ts`
|
||||
– Jednotliví poskytovatelé: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `qoder.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilo`codes`, `kilo`code
|
||||
- Tenký obal: `src/lib/oauth/providers.ts` — reexporty z jednotlivých modulů## 3) Persistence Layer
|
||||
|
||||
## 3) Persistence Layer
|
||||
Primární stav DB (SQLite):
|
||||
|
||||
Primary state DB (SQLite):
|
||||
- Základní jádro: `src/lib/db/core.ts` (better-sqlite3, migrace, WAL)
|
||||
- Fasáda pro reexport: `src/lib/localDb.ts` (tenká vrstva kompatibility pro volající)
|
||||
- soubor: `${DATA_DIR}/storage.sqlite` (nebo `$XDG_CONFIG_HOME/omniroute/storage.sqlite`, pokud je nastaven, jinak `~/.omniroute/storage.sqlite`)
|
||||
- entity (tabulky + jmenné prostory KV): providerConnections, providerNodes, modelAliases, komba, apiKeys, nastavení, ceny,**customModels**,**proxyConfig**,**ipFilter**,**thinkingBudget**,**systemPrompt**
|
||||
|
||||
- Core infra: `src/lib/db/core.ts` (better-sqlite3, migrations, WAL)
|
||||
- Re-export facade: `src/lib/localDb.ts` (thin compatibility layer for callers)
|
||||
- file: `${DATA_DIR}/storage.sqlite` (or `$XDG_CONFIG_HOME/omniroute/storage.sqlite` when set, else `~/.omniroute/storage.sqlite`)
|
||||
- entities (tables + KV namespaces): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
||||
Perzistence při používání:
|
||||
|
||||
Usage persistence:
|
||||
- fasáda: `src/lib/usageDb.ts` (rozložené moduly v `src/lib/usage/*`)
|
||||
- SQLite tabulky v `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
|
||||
- volitelné artefakty souborů zůstávají kvůli kompatibilitě/ladění (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `<repo>/logs/...`)
|
||||
- starší soubory JSON jsou migrovány do SQLite migrací při spuštění, pokud jsou k dispozici
|
||||
|
||||
- facade: `src/lib/usageDb.ts` (decomposed modules in `src/lib/usage/*`)
|
||||
- SQLite tables in `storage.sqlite`: `usage_history`, `call_logs`, `proxy_logs`
|
||||
- optional file artifacts remain for compatibility/debug (`${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`, `<repo>/logs/...`)
|
||||
- legacy JSON files are migrated to SQLite by startup migrations when present
|
||||
Stavová databáze domény (SQLite):
|
||||
|
||||
Domain State DB (SQLite):
|
||||
- `src/lib/db/domainState.ts` — operace CRUD pro stav domény
|
||||
– Tabulky (vytvořené v `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Vzor mezipaměti pro zápis: mapy v paměti jsou autoritativní za běhu; mutace se zapisují synchronně do SQLite; stav je obnoven z DB při studeném startu## 4) Auth + Security Surfaces
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD operations for domain state
|
||||
- Tables (created in `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Write-through cache pattern: in-memory Maps are authoritative at runtime; mutations are written synchronously to SQLite; state is restored from DB on cold start
|
||||
- Ověření souboru cookie řídicího panelu: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
||||
- Generování/ověření klíče API: `src/shared/utils/apiKey.ts`
|
||||
- Tajné informace poskytovatele zůstaly v položkách `providerConnections`
|
||||
- Podpora odchozích proxy přes `open-sse/utils/proxyFetch.ts` (env vars) a `open-sse/utils/networkProxy.ts` (konfigurovatelné pro jednotlivé poskytovatele nebo globální)## 5) Cloud Sync
|
||||
|
||||
## 4) Auth + Security Surfaces
|
||||
|
||||
- Dashboard cookie auth: `src/proxy.ts`, `src/app/api/auth/login/route.ts`
|
||||
- API key generation/verification: `src/shared/utils/apiKey.ts`
|
||||
- Provider secrets persisted in `providerConnections` entries
|
||||
- Outbound proxy support via `open-sse/utils/proxyFetch.ts` (env vars) and `open-sse/utils/networkProxy.ts` (configurable per-provider or global)
|
||||
|
||||
## 5) Cloud Sync
|
||||
|
||||
- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
|
||||
- Periodic task: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Periodic task: `src/shared/services/modelSyncScheduler.ts`
|
||||
- Control route: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Request Lifecycle (`/v1/chat/completions`)
|
||||
- Init plánovače: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`, `src/shared/services/modelSyncScheduler.ts`
|
||||
- Pravidelný úkol: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Pravidelný úkol: `src/shared/services/modelSyncScheduler.ts`
|
||||
- Řídící cesta: `src/app/api/sync/cloud/route.ts`## Request Lifecycle (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -358,9 +338,7 @@ flowchart TD
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics. Combo routing adds one extra guard: provider-scoped 400s such as upstream content-block and role-validation failures are treated as model-local failures so later combo targets can still run.
|
||||
|
||||
## OAuth Onboarding and Token Refresh Lifecycle
|
||||
Záložní rozhodnutí jsou řízena `open-sse/services/accountFallback.ts` pomocí stavových kódů a heuristiky chybových zpráv. Kombinované směrování přidává ještě jednu ochranu: 400s v rozsahu poskytovatele, jako jsou selhání blokování obsahu a ověřování rolí, jsou považovány za lokální selhání modelu, takže pozdější kombinované cíle mohou stále běžet.## OAuth Onboarding and Token Refresh Lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -390,9 +368,7 @@ sequenceDiagram
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
||||
|
||||
## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
Obnovení během živého provozu se provádí uvnitř `open-sse/handlers/chatCore.ts` prostřednictvím spouštěče `refreshCredentials()`.## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -424,9 +400,7 @@ sequenceDiagram
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
|
||||
|
||||
## Data Model and Storage Map
|
||||
Pravidelnou synchronizaci spouští „CloudSyncScheduler“, když je povolen cloud.## Data Model and Storage Map
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
@@ -527,14 +501,12 @@ erDiagram
|
||||
}
|
||||
```
|
||||
|
||||
Physical storage files:
|
||||
Soubory fyzického úložiště:
|
||||
|
||||
- primary runtime DB: `${DATA_DIR}/storage.sqlite`
|
||||
- request log lines: `${DATA_DIR}/log.txt` (compat/debug artifact)
|
||||
- structured call payload archives: `${DATA_DIR}/call_logs/`
|
||||
- optional translator/request debug sessions: `<repo>/logs/...`
|
||||
|
||||
## Deployment Topology
|
||||
- primární runtime DB: `${DATA_DIR}/storage.sqlite`
|
||||
- řádky protokolu požadavku: `${DATA_DIR}/log.txt` (artefakt compat/debug)
|
||||
- archivy strukturovaného obsahu volání: `${DATA_DIR}/call_logs/`
|
||||
- volitelné relace ladění překladatele/požadavku: `<repo>/logs/...`## Deployment Topology
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -569,246 +541,205 @@ flowchart LR
|
||||
|
||||
### Route and API Modules
|
||||
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: compatibility APIs
|
||||
- `src/app/api/v1/providers/[provider]/*`: dedicated per-provider routes (chat, embeddings, images)
|
||||
- `src/app/api/providers*`: provider CRUD, validation, testing
|
||||
- `src/app/api/provider-nodes*`: custom compatible node management
|
||||
- `src/app/api/provider-models`: custom model management (CRUD)
|
||||
- `src/app/api/models/route.ts`: model catalog API (aliases + custom models)
|
||||
- `src/app/api/oauth/*`: OAuth/device-code flows
|
||||
- `src/app/api/keys*`: local API key lifecycle
|
||||
- `src/app/api/models/alias`: alias management
|
||||
- `src/app/api/combos*`: fallback combo management
|
||||
- `src/app/api/pricing`: pricing overrides for cost calculation
|
||||
- `src/app/api/settings/proxy`: proxy configuration (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: outbound proxy connectivity test (POST)
|
||||
- `src/app/api/usage/*`: usage and logs APIs
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloud sync and cloud-facing helpers
|
||||
- `src/app/api/cli-tools/*`: local CLI config writers/checkers
|
||||
- `src/app/api/settings/ip-filter`: IP allowlist/blocklist (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: thinking token budget config (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: global system prompt (GET/PUT)
|
||||
- `src/app/api/sessions`: active session listing (GET)
|
||||
- `src/app/api/rate-limits`: per-account rate limit status (GET)
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: rozhraní API pro kompatibilitu
|
||||
- `src/app/api/v1/providers/[poskytovatel]/*`: vyhrazené trasy pro jednotlivé poskytovatele (chat, vkládání, obrázky)
|
||||
- `src/app/api/providers*`: poskytovatel CRUD, ověření, testování
|
||||
- `src/app/api/provider-nodes*`: vlastní kompatibilní správa uzlů
|
||||
- `src/app/api/provider-models`: správa vlastních modelů (CRUD)
|
||||
- `src/app/api/models/route.ts`: API katalogu modelů (aliasy + vlastní modely)
|
||||
- `src/app/api/oauth/*`: toky OAuth/kódu zařízení
|
||||
- `src/app/api/keys*`: životní cyklus místního klíče API
|
||||
- `src/app/api/models/alias`: správa aliasů
|
||||
- `src/app/api/combos*`: správa záložních kombinací
|
||||
- `src/app/api/pricing`: přepisy cen pro výpočet nákladů
|
||||
- `src/app/api/settings/proxy`: konfigurace proxy (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: test odchozího proxy připojení (POST)
|
||||
- `src/app/api/usage/*`: využití a protokoly API
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: cloudová synchronizace a pomocníci pro cloud
|
||||
- `src/app/api/cli-tools/*`: místní zapisovače/kontroly konfigurace CLI
|
||||
- `src/app/api/settings/ip-filter`: seznam povolených/blokovaných IP adres (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: konfigurace rozpočtu tokenu myšlení (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: globální systémová výzva (GET/PUT)
|
||||
- `src/app/api/sessions`: seznam aktivních relací (GET)
|
||||
- `src/app/api/rate-limits`: stav limitu sazby na účet (GET)### Routing and Execution Core
|
||||
|
||||
### Routing and Execution Core
|
||||
- `src/sse/handlers/chat.ts`: analýza požadavků, zpracování kombinací, smyčka výběru účtu
|
||||
- `open-sse/handlers/chatCore.ts`: překlad, odeslání exekutora, zpracování opakování/obnovení, nastavení streamu
|
||||
- `open-sse/executors/*`: chování sítě a formátu specifické pro poskytovatele### Translation Registry and Format Converters
|
||||
|
||||
- `src/sse/handlers/chat.ts`: request parse, combo handling, account selection loop
|
||||
- `open-sse/handlers/chatCore.ts`: translation, executor dispatch, retry/refresh handling, stream setup
|
||||
- `open-sse/executors/*`: provider-specific network and format behavior
|
||||
- `open-sse/translator/index.ts`: registr a orchestrace překladatelů
|
||||
- Požadavek na překladatele: `open-sse/translator/request/*`
|
||||
- Překladače odpovědí: `open-sse/translator/response/*`
|
||||
- Formátové konstanty: `open-sse/translator/formats.ts`### Persistence
|
||||
|
||||
### Translation Registry and Format Converters
|
||||
- `src/lib/db/*`: trvalá trvalá konfigurace/stav a doména na SQLite
|
||||
- `src/lib/localDb.ts`: reexport kompatibility pro moduly DB
|
||||
- `src/lib/usageDb.ts`: fasáda historie použití/protokolů volání nad tabulkami SQLite## Provider Executor Coverage (Strategy Pattern)
|
||||
|
||||
- `open-sse/translator/index.ts`: translator registry and orchestration
|
||||
- Request translators: `open-sse/translator/request/*`
|
||||
- Response translators: `open-sse/translator/response/*`
|
||||
- Format constants: `open-sse/translator/formats.ts`
|
||||
Každý poskytovatel má specializovaný spouštěč rozšiřující `BaseExecutor` (v `open-sse/executors/base.ts`), který poskytuje vytváření URL, konstrukci záhlaví, opakování s exponenciálním stažením, háky pro obnovení pověření a metodu orchestrace `execute()`.
|
||||
|
||||
### Persistence
|
||||
| Exekutor | Poskytovatel(é) | Speciální manipulace |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamická konfigurace URL/záhlaví na poskytovatele |
|
||||
| "AntigravityExecutor" | Google Antigravity | Vlastní ID projektů/relací, Opakovat po analýze |
|
||||
| "CodexExecutor" | Kodex OpenAI | Vkládá systémové instrukce, nutí k logickému úsilí |
|
||||
| `CursorExecutor` | Kurzor IDE | Protokol ConnectRPC, kódování Protobuf, podepisování požadavků pomocí kontrolního součtu |
|
||||
| "GithubExecutor" | GitHub Copilot | Obnovení tokenu druhého pilota, hlavičky napodobující VSCode |
|
||||
| "KiroExecutor" | AWS CodeWhisperer/Kiro | Binární formát AWS EventStream → konverze SSE |
|
||||
| "GeminiCLIExecutor" | Gemini CLI | Cyklus obnovení tokenu Google OAuth |
|
||||
|
||||
- `src/lib/db/*`: persistent config/state and domain persistence on SQLite
|
||||
- `src/lib/localDb.ts`: compatibility re-export for DB modules
|
||||
- `src/lib/usageDb.ts`: usage history/call logs facade on top of SQLite tables
|
||||
Všichni ostatní poskytovatelé (včetně vlastních kompatibilních uzlů) používají `DefaultExecutor`.## Provider Compatibility Matrix
|
||||
|
||||
## Provider Executor Coverage (Strategy Pattern)
|
||||
| Poskytovatel | Formát | Auth | Stream | Nestreamovat | Obnovení tokenu | Použití API |
|
||||
| ---------------- | ---------------- | ------------------------ | -------------------- | ------------ | --------------- | ------------------- | ------------------------------ |
|
||||
| Claude | claude | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Pouze správce |
|
||||
| Blíženci | Blíženci | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole |
|
||||
| Antigravitace | antigravitace | OAuth | ✅ | ✅ | ✅ | ✅ Plná kvóta API |
|
||||
| OpenAI | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Codex | openai-responses | OAuth | ✅ nuceně | ❌ | ✅ | ✅ Sazbové limity |
|
||||
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Snímky kvót |
|
||||
| Kurzor | kurzor | Vlastní kontrolní součet | ✅ | ✅ | ❌ | ❌ |
|
||||
| Kiro | kiro | AWS SSO OIDC | ✅ (Stream událostí) | ❌ | ✅ | ✅ Limity použití |
|
||||
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Na vyžádání |
|
||||
| Qoder | openai | OAuth (základní) | ✅ | ✅ | ✅ | ⚠️ Na vyžádání |
|
||||
| OpenRouter | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Kimi/MiniMax | claude | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Mistral | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Zmatenost | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Společně AI | openai | Klíč API | ✅ | ✅ | ❌ | ❌ |
|
||||
| Ohňostroje AI | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cerebras | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cohere | openai | API klíč | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | openai | API klíč | ✅ | ✅ | ❌ | ❌ | ## Format Translation Coverage |
|
||||
|
||||
Each provider has a specialized executor extending `BaseExecutor` (in `open-sse/executors/base.ts`), which provides URL building, header construction, retry with exponential backoff, credential refresh hooks, and the `execute()` orchestration method.
|
||||
Mezi zjištěné zdrojové formáty patří:
|
||||
|
||||
| Executor | Provider(s) | Special Handling |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, Qoder, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Dynamic URL/header config per provider |
|
||||
| `AntigravityExecutor` | Google Antigravity | Custom project/session IDs, Retry-After parsing |
|
||||
| `CodexExecutor` | OpenAI Codex | Injects system instructions, forces reasoning effort |
|
||||
| `CursorExecutor` | Cursor IDE | ConnectRPC protocol, Protobuf encoding, request signing via checksum |
|
||||
| `GithubExecutor` | GitHub Copilot | Copilot token refresh, VSCode-mimicking headers |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/Kiro | AWS EventStream binary format → SSE conversion |
|
||||
| `GeminiCLIExecutor` | Gemini CLI | Google OAuth token refresh cycle |
|
||||
- "openai".
|
||||
- "openai-odpovědi".
|
||||
- "claude".
|
||||
- "blíženci".
|
||||
|
||||
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
|
||||
Mezi cílové formáty patří:
|
||||
|
||||
## Provider Compatibility Matrix
|
||||
|
||||
| Provider | Format | Auth | Stream | Non-Stream | Token Refresh | Usage API |
|
||||
| ---------------- | ---------------- | --------------------- | ---------------- | ---------- | ------------- | ------------------ |
|
||||
| Claude | claude | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Admin only |
|
||||
| Gemini | gemini | API Key / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloud Console |
|
||||
| Antigravity | antigravity | OAuth | ✅ | ✅ | ✅ | ✅ Full quota API |
|
||||
| OpenAI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Codex | openai-responses | OAuth | ✅ forced | ❌ | ✅ | ✅ Rate limits |
|
||||
| GitHub Copilot | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Quota snapshots |
|
||||
| Cursor | cursor | Custom checksum | ✅ | ✅ | ❌ | ❌ |
|
||||
| Kiro | kiro | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Usage limits |
|
||||
| Qwen | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ Per request |
|
||||
| Qoder | openai | OAuth (Basic) | ✅ | ✅ | ✅ | ⚠️ Per request |
|
||||
| OpenRouter | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Kimi/MiniMax | claude | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Mistral | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Perplexity | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Together AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Fireworks AI | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cerebras | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cohere | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | openai | API Key | ✅ | ✅ | ❌ | ❌ |
|
||||
|
||||
## Format Translation Coverage
|
||||
|
||||
Detected source formats include:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
Target formats include:
|
||||
|
||||
- OpenAI chat/Responses
|
||||
- OpenAI chat/odpovědi
|
||||
- Claude
|
||||
- Gemini/Gemini-CLI/Antigravity envelope
|
||||
- Gemini/Gemini-CLI/Antigravitační obálka
|
||||
- Kiro
|
||||
- Cursor
|
||||
- Kurzor
|
||||
|
||||
Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
|
||||
|
||||
```
|
||||
Překlady používají**OpenAI jako formát centra**— všechny konverze procházejí přes OpenAI jako prostředník:```
|
||||
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:
|
||||
Překlady jsou vybírány dynamicky na základě tvaru zdrojové užitečné zátěže a cílového formátu poskytovatele.
|
||||
|
||||
- **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`
|
||||
Další vrstvy zpracování v překladovém potrubí:
|
||||
|
||||
## Supported API Endpoints
|
||||
-**Dezinfekce odezvy**– Odstraňuje nestandardní pole z odpovědí ve formátu OpenAI (streamovaných i nestreamovaných), aby byla zajištěna přísná shoda se sadou SDK
|
||||
-**Normalizace rolí**— Převádí `vývojář` → `systém` pro jiné cíle než OpenAI; sloučí `systém` → `uživatel` pro modely, které odmítají systémovou roli (GLM, ERNIE)
|
||||
–**Extrakce značek Think**– analyzuje bloky „<think>...</think>“ z obsahu do pole „reasoning_content“
|
||||
–**Strukturovaný výstup**– Převádí OpenAI `response_format.json_schema` na Gemini `responseMimeType` + `responseSchema`## Supported API Endpoints
|
||||
|
||||
| Endpoint | Format | Handler |
|
||||
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------- |
|
||||
| `POST /v1/chat/completions` | OpenAI Chat | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Claude Messages | Same handler (auto-detected) |
|
||||
| `POST /v1/responses` | OpenAI Responses | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | Model listing | API route |
|
||||
| `POST /v1/images/generations` | OpenAI Images | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | Model listing | API route |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | OpenAI Chat | Dedicated per-provider with model validation |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Dedicated per-provider with model validation |
|
||||
| `POST /v1/providers/{provider}/images/generations` | OpenAI Images | Dedicated per-provider with model validation |
|
||||
| `POST /v1/messages/count_tokens` | Claude Token Count | API route |
|
||||
| `GET /v1/models` | OpenAI Models list | API route (chat + embedding + image + custom models) |
|
||||
| `GET /api/models/catalog` | Catalog | All models grouped by provider + type |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Gemini native | API route |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Proxy Config | Network proxy configuration |
|
||||
| `POST /api/settings/proxy/test` | Proxy Connectivity | Proxy health/connectivity test endpoint |
|
||||
| `GET/POST/DELETE /api/provider-models` | Provider Models | Provider model metadata backing custom and managed available models |
|
||||
| Koncový bod | Formát | Psovod |
|
||||
| --------------------------------------------------- | ------------------- | -------------------------------------------------------------------- |
|
||||
| `POST /v1/chat/completions` | Chat OpenAI | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Claude Messages | Stejná obsluha (automaticky zjištěna) |
|
||||
| `POST /v1/responses` | Odezvy OpenAI | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI Embeddings | `open-sse/handlers/embeddings.ts` |
|
||||
| `ZÍSKAT /v1/embeddings` | Seznam modelů | Cesta API |
|
||||
| `POST /v1/images/generations` | Obrázky OpenAI | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `ZÍSKAT /v1/images/generations` | Seznam modelů | Cesta API |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | Chat OpenAI | Vyhrazené na poskytovatele s ověřením modelu |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI Embeddings | Vyhrazené na poskytovatele s ověřením modelu |
|
||||
| `POST /v1/providers/{poskytovatel}/images/generations` | Obrázky OpenAI | Vyhrazené na poskytovatele s ověřením modelu |
|
||||
| `POST /v1/messages/count_tokens` | Počet tokenů Claude | Cesta API |
|
||||
| `GET /v1/models` | Seznam modelů OpenAI | Cesta API (chat + vkládání + obrázek + vlastní modely) |
|
||||
| `GET /api/models/catalog` | Katalog | Všechny modely seskupené podle poskytovatele + typ |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Blíženec domorodec | Cesta API |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Konfigurace proxy | Konfigurace síťového proxy |
|
||||
| `POST /api/settings/proxy/test` | Připojení proxy | Koncový bod testu stavu proxy/konektivity |
|
||||
| `GET/POST/DELETE /api/provider-models` | Modely poskytovatelů | Vlastní a spravované dostupné modely podporují metadata modelu poskytovatele |## Bypass Handler
|
||||
|
||||
## Bypass Handler
|
||||
Obslužná rutina bypassu (`open-sse/utils/bypassHandler.ts`) zachycuje známé požadavky na „zahození“ od Claude CLI – zahřívací pingy, extrakce titulů a počty tokenů – a vrací**falešnou odpověď**, aniž by spotřebovával tokeny poskytovatele upstream. To se spustí pouze v případě, že `User-Agent` obsahuje `claude-cli`.## Request Logger Pipeline
|
||||
|
||||
The bypass handler (`open-sse/utils/bypassHandler.ts`) intercepts known "throwaway" requests from Claude CLI — warmup pings, title extractions, and token counts — and returns a **fake response** without consuming upstream provider tokens. This is triggered only when `User-Agent` contains `claude-cli`.
|
||||
|
||||
## Request Logger Pipeline
|
||||
|
||||
The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
Záznamník požadavků (`open-sse/utils/requestLogger.ts`) poskytuje 7fázový kanál protokolování ladění, který je ve výchozím nastavení vypnutý, povolený pomocí `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
|
||||
```
|
||||
````
|
||||
|
||||
Files are written to `<repo>/logs/<session>/` for each request session.
|
||||
|
||||
## Failure Modes and Resilience
|
||||
Soubory se zapisují do `<repo>/logs/<session>/` pro každou relaci požadavku.## Failure Modes and Resilience
|
||||
|
||||
## 1) Account/Provider Availability
|
||||
|
||||
- provider account cooldown on transient/rate/auth errors
|
||||
- account fallback before failing request
|
||||
- combo model fallback when current model/provider path is exhausted
|
||||
- Cooldown účtu poskytovatele při přechodných chybách/chybách rychlosti/autorizace
|
||||
- záložní účet před neúspěšným žádostí
|
||||
- Záloha kombinovaného modelu, když je vyčerpána aktuální cesta modelu/poskytovatele## 2) Token Expiry
|
||||
|
||||
## 2) Token Expiry
|
||||
- Předběžná kontrola a obnovení s opakovaným pokusem pro poskytovatele obnovitelných zdrojů
|
||||
- 401/403 opakování po pokusu o obnovení v cestě jádra## 3) Stream Safety
|
||||
|
||||
- pre-check and refresh with retry for refreshable providers
|
||||
- 401/403 retry after refresh attempt in core path
|
||||
- řadič toku s vědomím odpojení
|
||||
- překladový proud s vyprázdněním konce proudu a zpracováním `[DONE]`
|
||||
- záložní odhad využití, když chybí metadata využití poskytovatele## 4) Cloud Sync Degradation
|
||||
|
||||
## 3) Stream Safety
|
||||
- Objeví se chyby synchronizace, ale místní běh pokračuje
|
||||
- plánovač má logiku umožňující opakování, ale periodické spouštění aktuálně standardně volá synchronizaci na jeden pokus## 5) Data Integrity
|
||||
|
||||
- disconnect-aware stream controller
|
||||
- translation stream with end-of-stream flush and `[DONE]` handling
|
||||
- usage estimation fallback when provider usage metadata is missing
|
||||
- Migrace schémat SQLite a automatické upgrady při spuštění
|
||||
- starší cesta ke kompatibilitě migrace JSON → SQLite## Observability and Operational Signals
|
||||
|
||||
## 4) Cloud Sync Degradation
|
||||
Zdroje viditelnosti za běhu:
|
||||
|
||||
- sync errors are surfaced but local runtime continues
|
||||
- scheduler has retry-capable logic, but periodic execution currently calls single-attempt sync by default
|
||||
- protokoly konzoly z `src/sse/utils/logger.ts`
|
||||
- agregáty využití na žádost v SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- čtyřfázové podrobné zachycení užitečného zatížení v SQLite (`request_detail_logs`), když `settings.detailed_logs_enabled=true`
|
||||
- textový protokol o stavu požadavku v `log.txt` (nepovinné/kompatibilní)
|
||||
- volitelné protokoly hlubokých požadavků/překladů pod `logs/`, když `ENABLE_REQUEST_LOGS=true`
|
||||
- koncové body využití řídicího panelu (`/api/usage/*`) pro spotřebu uživatelského rozhraní
|
||||
|
||||
## 5) Data Integrity
|
||||
Podrobné zachycení datové části požadavku ukládá až čtyři fáze datové zátěže JSON na směrované volání:
|
||||
|
||||
- SQLite schema migrations and auto-upgrade hooks at startup
|
||||
- legacy JSON → SQLite migration compatibility path
|
||||
- nezpracovaný požadavek přijatý od klienta
|
||||
- přeložená žádost skutečně odeslaná proti proudu
|
||||
- odpověď poskytovatele rekonstruovaná jako JSON; streamované odpovědi jsou komprimovány do konečného shrnutí plus metadata streamu
|
||||
- konečná odpověď klienta vrácená OmniRoute; streamované odpovědi jsou uloženy ve stejném kompaktním souhrnném formuláři## Security-Sensitive Boundaries
|
||||
|
||||
## Observability and Operational Signals
|
||||
- Tajný klíč JWT (`JWT_SECRET`) zajišťuje ověřování/podepisování souborů cookie relace řídicího panelu
|
||||
- Počáteční zaváděcí heslo (`INITIAL_PASSWORD`) by mělo být explicitně nakonfigurováno pro zřizování při prvním spuštění
|
||||
- Tajný klíč API HMAC (`API_KEY_SECRET`) zabezpečuje vygenerovaný formát lokálního klíče API
|
||||
- Tajné informace poskytovatele (klíče/tokeny API) jsou uloženy v místní databázi a měly by být chráněny na úrovni souborového systému
|
||||
- Koncové body synchronizace cloudu se spoléhají na sémantiku klíče API + ID počítače## Environment and Runtime Matrix
|
||||
|
||||
Runtime visibility sources:
|
||||
Proměnné prostředí aktivně používané kódem:
|
||||
|
||||
- console logs from `src/sse/utils/logger.ts`
|
||||
- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- four-stage detailed payload captures in SQLite (`request_detail_logs`) when `settings.detailed_logs_enabled=true`
|
||||
- textual request status log in `log.txt` (optional/compat)
|
||||
- optional deep request/translation logs under `logs/` when `ENABLE_REQUEST_LOGS=true`
|
||||
- dashboard usage endpoints (`/api/usage/*`) for UI consumption
|
||||
- Aplikace/auth: `JWT_SECRET`, `INITIAL_PASSWORD`
|
||||
- Úložiště: `DATA_DIR`
|
||||
- Kompatibilní chování uzlu: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Volitelné přepsání základny úložiště (Linux/macOS, když není `DATA_DIR` nastaveno): `XDG_CONFIG_HOME`
|
||||
– Bezpečnostní hash: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
||||
- Protokolování: `ENABLE_REQUEST_LOGS`
|
||||
– Synchronizace/cloudové URL: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
||||
– Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` a varianty s malými písmeny
|
||||
- Příznaky funkce SOCKS5: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Pomocníci platformy/běhu (nikoli konfigurace specifická pro aplikaci): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`## Known Architectural Notes
|
||||
|
||||
Detailed request payload capture stores up to four JSON payload stages per routed call:
|
||||
1. `usageDb` a `localDb` sdílejí stejnou zásadu základního adresáře (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) se starší migrací souborů.
|
||||
2. `/api/v1/route.ts` deleguje stejný tvůrce jednotného katalogu, který používá `/api/v1/models` (`src/app/api/v1/models/catalog.ts`), aby se zabránilo sémantickému posunu.
|
||||
3. Pokud je povoleno, zapisovač požadavku zapisuje celé záhlaví/tělo; považovat adresář log za citlivý.
|
||||
4. Chování cloudu závisí na správné dosažitelnosti koncového bodu cloudu „NEXT_PUBLIC_BASE_URL“.
|
||||
5. Adresář `open-sse/` je publikován jako balíček `@omniroute/open-sse`**npm workspace**. Zdrojový kód jej importuje přes `@omniroute/open-sse/...` (vyřešeno Next.js `transpilePackages`). Cesty k souborům v tomto dokumentu stále používají název adresáře `open-sse/` kvůli konzistenci.
|
||||
6. Grafy v řídicím panelu používají**Recharts**(založené na SVG) pro přístupné, interaktivní analytické vizualizace (sloupcové grafy využití modelu, tabulky rozdělení poskytovatelů s mírou úspěšnosti).
|
||||
7. E2E testy používají**Playwright**(`tests/e2e/`), spouštěné přes `npm run test:e2e`. Unit testy používají**Node.js test runner**(`tests/unit/`), spouštějí se přes `npm run test:unit`. Zdrojový kód pod `src/` je**TypeScript**(`.ts`/`.tsx`); pracovní prostor `open-sse/` zůstává JavaScriptem (`.js`).
|
||||
8. Stránka Nastavení je uspořádána do 5 záložek: Zabezpečení, Směrování (6 globálních strategií: fill-first, round-robin, p2c, náhodné, nejméně používané, nákladově optimalizované), Odolnost (upravitelné rychlostní limity, jistič, zásady), AI (rozpočet myšlení, systémová výzva, mezipaměť výzvy), Pokročilé (proxy).## Operational Verification Checklist
|
||||
|
||||
- raw request received from the client
|
||||
- translated request actually sent upstream
|
||||
- provider response reconstructed as JSON; streamed responses are compacted to the final summary plus stream metadata
|
||||
- final client response returned by OmniRoute; streamed responses are stored in the same compact summary form
|
||||
|
||||
## Security-Sensitive Boundaries
|
||||
|
||||
- JWT secret (`JWT_SECRET`) secures dashboard session cookie verification/signing
|
||||
- Initial password bootstrap (`INITIAL_PASSWORD`) should be explicitly configured for first-run provisioning
|
||||
- API key HMAC secret (`API_KEY_SECRET`) secures generated local API key format
|
||||
- Provider secrets (API keys/tokens) are persisted in local DB and should be protected at filesystem level
|
||||
- Cloud sync endpoints rely on API key auth + machine id semantics
|
||||
|
||||
## Environment and Runtime Matrix
|
||||
|
||||
Environment variables actively used by code:
|
||||
|
||||
- App/auth: `JWT_SECRET`, `INITIAL_PASSWORD`
|
||||
- Storage: `DATA_DIR`
|
||||
- Compatible node behavior: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Optional storage base override (Linux/macOS when `DATA_DIR` unset): `XDG_CONFIG_HOME`
|
||||
- Security hashing: `API_KEY_SECRET`, `MACHINE_ID_SALT`
|
||||
- Logging: `ENABLE_REQUEST_LOGS`
|
||||
- Sync/cloud URLing: `NEXT_PUBLIC_BASE_URL`, `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Outbound proxy: `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` and lowercase variants
|
||||
- SOCKS5 feature flags: `ENABLE_SOCKS5_PROXY`, `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Platform/runtime helpers (not app-specific config): `APPDATA`, `NODE_ENV`, `PORT`, `HOSTNAME`
|
||||
|
||||
## Known Architectural Notes
|
||||
|
||||
1. `usageDb` and `localDb` share the same base directory policy (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) with legacy file migration.
|
||||
2. `/api/v1/route.ts` delegates to the same unified catalog builder used by `/api/v1/models` (`src/app/api/v1/models/catalog.ts`) to avoid semantic drift.
|
||||
3. Request logger writes full headers/body when enabled; treat log directory as sensitive.
|
||||
4. Cloud behavior depends on correct `NEXT_PUBLIC_BASE_URL` and cloud endpoint reachability.
|
||||
5. The `open-sse/` directory is published as the `@omniroute/open-sse` **npm workspace package**. Source code imports it via `@omniroute/open-sse/...` (resolved by Next.js `transpilePackages`). File paths in this document still use the directory name `open-sse/` for consistency.
|
||||
6. Charts in the dashboard use **Recharts** (SVG-based) for accessible, interactive analytics visualizations (model usage bar charts, provider breakdown tables with success rates).
|
||||
7. E2E tests use **Playwright** (`tests/e2e/`), run via `npm run test:e2e`. Unit tests use **Node.js test runner** (`tests/unit/`), run via `npm run test:unit`. Source code under `src/` is **TypeScript** (`.ts`/`.tsx`); the `open-sse/` workspace remains JavaScript (`.js`).
|
||||
8. Settings page is organized into 5 tabs: Security, Routing (6 global strategies: fill-first, round-robin, p2c, random, least-used, cost-optimized), Resilience (editable rate limits, circuit breaker, policies), AI (thinking budget, system prompt, prompt cache), Advanced (proxy).
|
||||
|
||||
## Operational Verification Checklist
|
||||
|
||||
- Build from source: `npm run build`
|
||||
- Build Docker image: `docker build -t omniroute .`
|
||||
- Start service and verify:
|
||||
- Sestavení ze zdroje: `npm run build`
|
||||
- Sestavení obrazu Dockeru: `docker build -t omniroute .`
|
||||
- Spusťte službu a ověřte:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- CLI target base URL should be `http://<host>:20128/v1` when `PORT=20128`
|
||||
- Základní adresa URL cíle CLI by měla být `http://<hostitel>:20128/v1`, když `PORT=20128`
|
||||
|
||||
@@ -1,45 +1,32 @@
|
||||
# OmniRoute Auto-Combo Engine (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/AUTO-COMBO.md) · 🇪🇸 [es](../../es/docs/AUTO-COMBO.md) · 🇫🇷 [fr](../../fr/docs/AUTO-COMBO.md) · 🇩🇪 [de](../../de/docs/AUTO-COMBO.md) · 🇮🇹 [it](../../it/docs/AUTO-COMBO.md) · 🇷🇺 [ru](../../ru/docs/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/AUTO-COMBO.md) · 🇯🇵 [ja](../../ja/docs/AUTO-COMBO.md) · 🇰🇷 [ko](../../ko/docs/AUTO-COMBO.md) · 🇸🇦 [ar](../../ar/docs/AUTO-COMBO.md) · 🇮🇳 [hi](../../hi/docs/AUTO-COMBO.md) · 🇮🇳 [in](../../in/docs/AUTO-COMBO.md) · 🇹🇭 [th](../../th/docs/AUTO-COMBO.md) · 🇻🇳 [vi](../../vi/docs/AUTO-COMBO.md) · 🇮🇩 [id](../../id/docs/AUTO-COMBO.md) · 🇲🇾 [ms](../../ms/docs/AUTO-COMBO.md) · 🇳🇱 [nl](../../nl/docs/AUTO-COMBO.md) · 🇵🇱 [pl](../../pl/docs/AUTO-COMBO.md) · 🇸🇪 [sv](../../sv/docs/AUTO-COMBO.md) · 🇳🇴 [no](../../no/docs/AUTO-COMBO.md) · 🇩🇰 [da](../../da/docs/AUTO-COMBO.md) · 🇫🇮 [fi](../../fi/docs/AUTO-COMBO.md) · 🇵🇹 [pt](../../pt/docs/AUTO-COMBO.md) · 🇷🇴 [ro](../../ro/docs/AUTO-COMBO.md) · 🇭🇺 [hu](../../hu/docs/AUTO-COMBO.md) · 🇧🇬 [bg](../../bg/docs/AUTO-COMBO.md) · 🇸🇰 [sk](../../sk/docs/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/AUTO-COMBO.md) · 🇮🇱 [he](../../he/docs/AUTO-COMBO.md) · 🇵🇭 [phi](../../phi/docs/AUTO-COMBO.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/AUTO-COMBO.md) · 🇨🇿 [cs](../../cs/docs/AUTO-COMBO.md) · 🇹🇷 [tr](../../tr/docs/AUTO-COMBO.md)
|
||||
|
||||
---
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
> Samořídící modelové řetězce s adaptivním bodováním## How It Works
|
||||
|
||||
## How It Works
|
||||
Auto-Combo Engine dynamicky vybírá nejlepšího poskytovatele/model pro každý požadavek pomocí**6faktorové skórovací funkce**:
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
| Faktor | Hmotnost | Popis |
|
||||
| :--------- | :------- | :---------------------------------------------- | ------------- |
|
||||
| Kvóta | 0,20 | Zbývající kapacita [0..1] |
|
||||
| Zdraví | 0,25 | Jistič: ZAVŘENO=1,0, POLOVINA=0,5, OTEVŘENO=0,0 |
|
||||
| CostInv | 0,20 | Inverzní náklady (levnější = vyšší skóre) |
|
||||
| LatencyInv | 0,15 | Inverzní latence p95 (rychlejší = vyšší) |
|
||||
| TaskFit | 0,10 | Model × úkol typ skóre fitness |
|
||||
| Stabilita | 0,10 | Nízký rozptyl v latenci/chybách | ## Mode Packs |
|
||||
|
||||
| Factor | Weight | Description |
|
||||
| :--------- | :----- | :---------------------------------------------- |
|
||||
| Quota | 0.20 | Remaining capacity [0..1] |
|
||||
| Health | 0.25 | Circuit breaker: CLOSED=1.0, HALF=0.5, OPEN=0.0 |
|
||||
| CostInv | 0.20 | Inverse cost (cheaper = higher score) |
|
||||
| LatencyInv | 0.15 | Inverse p95 latency (faster = higher) |
|
||||
| TaskFit | 0.10 | Model × task type fitness score |
|
||||
| Stability | 0.10 | Low variance in latency/errors |
|
||||
| Balíček | Zaměření | Hmotnost klíče |
|
||||
| :---------------------------- | :------------- | :--------------- | --------------- |
|
||||
| 🚀**Rychlá dodávka** | Rychlost | latenceInv: 0,35 |
|
||||
| 💰**Úspora nákladů** | Ekonomika | costInv: 0,40 |
|
||||
| 🎯**Kvalita na prvním místě** | Nejlepší model | taskFit: 0,40 |
|
||||
| 📡**Offline Friendly** | Dostupnost | kvóta: 0,40 | ## Self-Healing |
|
||||
|
||||
## Mode Packs
|
||||
-**Dočasné vyloučení**: Skóre < 0,2 → vyloučeno na 5 minut (postupné stažení, max. 30 minut) -**Informace o jističi**: OPEN → auto-excluded; HALF_OPEN → požadavky na sondu -**Režim incidentu**: >50 % OTEVŘENO → zakázat průzkum, maximalizovat stabilitu -**Cooldown recovery**: Po vyloučení je prvním požadavkem "sonda" se zkráceným časovým limitem## Bandit Exploration
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
5 % požadavků (konfigurovatelných) je směrováno k náhodným poskytovatelům k prozkoumání. Deaktivováno v režimu incidentu.## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
@@ -53,15 +40,13 @@ curl http://localhost:20128/api/combos/auto
|
||||
|
||||
## Task Fitness
|
||||
|
||||
30+ models scored across 6 task types (`coding`, `review`, `planning`, `analysis`, `debugging`, `documentation`). Supports wildcard patterns (e.g., `*-coder` → high coding score).
|
||||
Více než 30 modelů skórovalo v 6 typech úloh (`kódování`, `recenze`, `plánování`, `analýza`, `ladění`, `dokumentace`). Podporuje vzory zástupných znaků (např. `*-coder` → vysoké skóre kódování).## Files
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
| :------------------------------------------- | :------------------------------------ |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | Scoring function & pool normalization |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | Model × task fitness lookup |
|
||||
| `open-sse/services/autoCombo/engine.ts` | Selection logic, bandit, budget cap |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | Exclusion, probes, incident mode |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 weight profiles |
|
||||
| `src/app/api/combos/auto/route.ts` | REST API |
|
||||
| Soubor | Účel |
|
||||
| :------------------------------------------- | :--------------------------------------- |
|
||||
| `open-sse/services/autoCombo/scoring.ts` | Funkce skórování a normalizace fondu |
|
||||
| `open-sse/services/autoCombo/taskFitness.ts` | Model × hledání kondice úkolu |
|
||||
| `open-sse/services/autoCombo/engine.ts` | Logika výběru, bandita, rozpočtový strop |
|
||||
| `open-sse/services/autoCombo/selfHealing.ts` | Vyloučení, sondy, režim incidentu |
|
||||
| `open-sse/services/autoCombo/modePacks.ts` | 4 hmotnostní profily |
|
||||
| `src/app/api/combos/auto/route.ts` | REST API |
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
# CLI Tools Setup Guide — OmniRoute (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CLI-TOOLS.md) · 🇪🇸 [es](../../es/docs/CLI-TOOLS.md) · 🇫🇷 [fr](../../fr/docs/CLI-TOOLS.md) · 🇩🇪 [de](../../de/docs/CLI-TOOLS.md) · 🇮🇹 [it](../../it/docs/CLI-TOOLS.md) · 🇷🇺 [ru](../../ru/docs/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CLI-TOOLS.md) · 🇯🇵 [ja](../../ja/docs/CLI-TOOLS.md) · 🇰🇷 [ko](../../ko/docs/CLI-TOOLS.md) · 🇸🇦 [ar](../../ar/docs/CLI-TOOLS.md) · 🇮🇳 [hi](../../hi/docs/CLI-TOOLS.md) · 🇮🇳 [in](../../in/docs/CLI-TOOLS.md) · 🇹🇭 [th](../../th/docs/CLI-TOOLS.md) · 🇻🇳 [vi](../../vi/docs/CLI-TOOLS.md) · 🇮🇩 [id](../../id/docs/CLI-TOOLS.md) · 🇲🇾 [ms](../../ms/docs/CLI-TOOLS.md) · 🇳🇱 [nl](../../nl/docs/CLI-TOOLS.md) · 🇵🇱 [pl](../../pl/docs/CLI-TOOLS.md) · 🇸🇪 [sv](../../sv/docs/CLI-TOOLS.md) · 🇳🇴 [no](../../no/docs/CLI-TOOLS.md) · 🇩🇰 [da](../../da/docs/CLI-TOOLS.md) · 🇫🇮 [fi](../../fi/docs/CLI-TOOLS.md) · 🇵🇹 [pt](../../pt/docs/CLI-TOOLS.md) · 🇷🇴 [ro](../../ro/docs/CLI-TOOLS.md) · 🇭🇺 [hu](../../hu/docs/CLI-TOOLS.md) · 🇧🇬 [bg](../../bg/docs/CLI-TOOLS.md) · 🇸🇰 [sk](../../sk/docs/CLI-TOOLS.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CLI-TOOLS.md) · 🇮🇱 [he](../../he/docs/CLI-TOOLS.md) · 🇵🇭 [phi](../../phi/docs/CLI-TOOLS.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CLI-TOOLS.md) · 🇨🇿 [cs](../../cs/docs/CLI-TOOLS.md) · 🇹🇷 [tr](../../tr/docs/CLI-TOOLS.md)
|
||||
|
||||
---
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
Tato příručka vysvětluje, jak nainstalovat a nakonfigurovat všechny podporované nástroje CLI pro kódování AI
|
||||
používat**OmniRoute**jako jednotný backend, který vám poskytne centralizovanou správu klíčů,
|
||||
sledování nákladů, přepínání modelů a protokolování požadavků napříč každým nástrojem.---
|
||||
|
||||
## How It Works
|
||||
|
||||
@@ -22,118 +20,113 @@ Claude / Codex / OpenCode / Cline / KiloCode / Continue / Kiro / Cursor / Copilo
|
||||
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
**Výhody:**
|
||||
|
||||
- One API key to manage all tools
|
||||
- Cost tracking across all CLIs in the dashboard
|
||||
- Model switching without reconfiguring every tool
|
||||
- Works locally and on remote servers (VPS)
|
||||
|
||||
---
|
||||
- Jeden klíč API pro správu všech nástrojů
|
||||
- Sledování nákladů napříč všemi CLI na řídicím panelu
|
||||
- Přepínání modelů bez překonfigurování každého nástroje
|
||||
- Funguje lokálně i na vzdálených serverech (VPS)---
|
||||
|
||||
## Supported Tools (Dashboard Source of Truth)
|
||||
|
||||
The dashboard cards in `/dashboard/cli-tools` are generated from `src/shared/constants/cliTools.ts`.
|
||||
Current list (v3.0.0-rc.16):
|
||||
Karty řídicího panelu v `/dashboard/cli-tools` jsou generovány z `src/shared/constants/cliTools.ts`.
|
||||
Aktuální seznam (v3.0.0-rc.16):
|
||||
|
||||
| Tool | ID | Command | Setup Mode | Install Method |
|
||||
| ------------------ | ------------- | ---------- | ---------- | -------------- |
|
||||
| **Claude Code** | `claude` | `claude` | env | npm |
|
||||
| **OpenAI Codex** | `codex` | `codex` | custom | npm |
|
||||
| **Factory Droid** | `droid` | `droid` | custom | bundled/CLI |
|
||||
| **OpenClaw** | `openclaw` | `openclaw` | custom | bundled/CLI |
|
||||
| **Cursor** | `cursor` | app | guide | desktop app |
|
||||
| **Cline** | `cline` | `cline` | custom | npm |
|
||||
| **Kilo Code** | `kilo` | `kilocode` | custom | npm |
|
||||
| **Continue** | `continue` | extension | guide | VS Code |
|
||||
| **Antigravity** | `antigravity` | internal | mitm | OmniRoute |
|
||||
| **GitHub Copilot** | `copilot` | extension | custom | VS Code |
|
||||
| **OpenCode** | `opencode` | `opencode` | guide | npm |
|
||||
| **Kiro AI** | `kiro` | app/cli | mitm | desktop/CLI |
|
||||
| Nástroj | ID | Příkaz | Režim nastavení | Způsob instalace |
|
||||
| ------------------ | --------------- | --------------- | --------------- | ------------------- | -------------------------------------------- |
|
||||
| **Claude Code** | "claude" | "claude" | env | npm |
|
||||
| **Kodex OpenAI** | "kodex" | "kodex" | vlastní | npm |
|
||||
| **Factory Droid** | "droid" | "droid" | vlastní | svázaný/CLI |
|
||||
| **OpenClaw** | "otevřený spár" | "otevřený spár" | vlastní | svázaný/CLI |
|
||||
| **Kurzor** | "kurzor" | aplikace | průvodce | desktopová aplikace |
|
||||
| **Cline** | "cline" | "cline" | vlastní | npm |
|
||||
| **Kilokód** | "kilo" | "kilokód" | vlastní | npm |
|
||||
| **Pokračovat** | "pokračovat" | prodloužení | průvodce | VS kód |
|
||||
| **Antigravitace** | "antigravitace" | vnitřní | mitm | OmniRoute |
|
||||
| **GitHub Copilot** | "kopilot" | prodloužení | vlastní | VS kód |
|
||||
| **OpenCode** | "opencode" | "opencode" | průvodce | npm |
|
||||
| **Kiro AI** | "kiro" | aplikace/kli | mitm | desktop/CLI | ### CLI fingerprint sync (Agents + Settings) |
|
||||
|
||||
### CLI fingerprint sync (Agents + Settings)
|
||||
`/dashboard/agents` a `Nastavení > CLI Fingerprint` používají `src/shared/constants/cliCompatProviders.ts`.
|
||||
To udržuje ID poskytovatelů v souladu s kartami CLI a staršími ID.
|
||||
|
||||
`/dashboard/agents` and `Settings > CLI Fingerprint` use `src/shared/constants/cliCompatProviders.ts`.
|
||||
This keeps provider IDs aligned with CLI cards and legacy IDs.
|
||||
| CLI ID | ID poskytovatele otisků prstů |
|
||||
| ------------------------------------------------------------------------------------------------------ | ----------------------------- |
|
||||
| "kilo" | "kilokód" |
|
||||
| "kopilot" | `github` |
|
||||
| `claude` / `codex` / `antigravitace` / `kiro` / `kurzor` / `cline` / `opencode` / `droid` / `openclaw` | stejné ID |
|
||||
|
||||
| CLI ID | Fingerprint Provider ID |
|
||||
| ---------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| `kilo` | `kilocode` |
|
||||
| `copilot` | `github` |
|
||||
| `claude` / `codex` / `antigravity` / `kiro` / `cursor` / `cline` / `opencode` / `droid` / `openclaw` | same ID |
|
||||
|
||||
Legacy IDs still accepted for compatibility: `copilot`, `kimi-coding`, `qwen`.
|
||||
|
||||
---
|
||||
Z důvodu kompatibility jsou stále přijímána starší ID: `kopilot`, `kimi-coding`, `qwen`.---
|
||||
|
||||
## Step 1 — Get an OmniRoute API Key
|
||||
|
||||
1. Open the OmniRoute dashboard → **API Manager** (`/dashboard/api-manager`)
|
||||
2. Click **Create API Key**
|
||||
3. Give it a name (e.g. `cli-tools`) and select all permissions
|
||||
4. Copy the key — you'll need it for every CLI below
|
||||
1. Otevřete řídicí panel OmniRoute →**Správce rozhraní API**(`/dashboard/api-manager`)
|
||||
2. Klikněte na**Vytvořit klíč API**
|
||||
3. Pojmenujte jej (např. `cli-tools`) a vyberte všechna oprávnění
|
||||
4. Zkopírujte klíč – budete jej potřebovat pro každé CLI níže
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
> Váš klíč vypadá takto: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`---
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
Všechny nástroje založené na npm vyžadují Node.js 18+:```bash
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
|
||||
npm install -g @openai/codex
|
||||
|
||||
# OpenCode
|
||||
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
|
||||
npm install -g kilocode
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
|
||||
**Verify:**
|
||||
````
|
||||
|
||||
```bash
|
||||
**Ověřit:**```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
opencode --version # x.x.x
|
||||
cline --version # 2.x.x
|
||||
kilocode --version # x.x.x (or: kilo --version)
|
||||
kiro-cli --version # 1.x.x
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
## Step 3 — Set Global Environment Variables
|
||||
|
||||
Add to `~/.bashrc` (or `~/.zshrc`), then run `source ~/.bashrc`:
|
||||
Přidejte do `~/.bashrc` (nebo `~/.zshrc`), poté spusťte `source ~/.bashrc`:```bash
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
````
|
||||
|
||||
---
|
||||
> V případě**vzdáleného serveru**nahraďte `localhost:20128` IP nebo doménou serveru,
|
||||
> např. `http://192.168.0.15:20128`.---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
@@ -150,11 +143,9 @@ mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
````
|
||||
|
||||
**Test:** `claude "say hello"`
|
||||
|
||||
---
|
||||
**Test:**`claude "řekni ahoj"`---
|
||||
|
||||
### OpenAI Codex
|
||||
|
||||
@@ -166,9 +157,7 @@ apiBaseUrl: http://localhost:20128/v1
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
**Test:**`kodex "co je 2+2?"`---
|
||||
|
||||
### OpenCode
|
||||
|
||||
@@ -180,57 +169,45 @@ api_key = "sk-your-omniroute-key"
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
**Test:**`opencode`---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
**Režim CLI:**```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"apiProvider": "openai",
|
||||
"openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"openAiApiKey": "sk-your-omniroute-key"
|
||||
"apiProvider": "openai",
|
||||
"openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"openAiApiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**VS Code mode:**
|
||||
Cline extension settings → API Provider: `OpenAI Compatible` → Base URL: `http://localhost:20128/v1`
|
||||
````
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → Cline → Apply Config**.
|
||||
**Režim VS kódu:**
|
||||
Nastavení rozšíření Cline → Poskytovatel rozhraní API: `OpenAI Compatible` → Základní URL: `http://localhost:20128/v1`
|
||||
|
||||
---
|
||||
Nebo použijte řídicí panel OmniRoute →**Nástroje CLI → Cline → Apply Config**.---
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
**Režim CLI:**```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
````
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
**Nastavení VS kódu:**```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
````
|
||||
|
||||
---
|
||||
Nebo použijte řídicí panel OmniRoute →**Nástroje CLI → KiloCode → Apply Config**.---
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
Upravit `~/.continue/config.yaml`:```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
@@ -238,11 +215,9 @@ models:
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
````
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
Po úpravě restartujte kód VS.---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
@@ -259,65 +234,56 @@ kiro-cli status
|
||||
|
||||
### Cursor (Desktop App)
|
||||
|
||||
> **Note:** Cursor routes requests through its cloud. For OmniRoute integration,
|
||||
> enable **Cloud Endpoint** in OmniRoute Settings and use your public domain URL.
|
||||
> **Poznámka:**Kurzor směruje požadavky přes svůj cloud. Pro integraci OmniRoute,
|
||||
> povolte**Cloud Endpoint**v nastavení OmniRoute a použijte adresu URL své veřejné domény.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
Přes GUI:**Nastavení → Modely → Klíč OpenAI API**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
– Základní adresa URL: „https://vase-domena.com/v1“.
|
||||
|
||||
---
|
||||
- API Key: váš klíč OmniRoute---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
Řídicí panel OmniRoute automatizuje konfiguraci pro většinu nástrojů:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
1. Přejděte na `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Rozbalte libovolnou kartu nástroje
|
||||
3. Z rozevírací nabídky vyberte klíč API
|
||||
4. Klikněte na**Apply Config**(pokud je nástroj detekován jako nainstalovaný)
|
||||
5. Nebo ručně zkopírujte vygenerovaný konfigurační fragment---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
**Droid**a**OpenClaw**jsou agenti umělé inteligence zabudovaní přímo do OmniRoute – není potřeba žádná instalace.
|
||||
Běží jako interní trasy a automaticky používají modelové směrování OmniRoute.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
- Přístup: `http://localhost:20128/dashboard/agents`
|
||||
- Konfigurace: stejná komba a poskytovatelé jako všechny ostatní nástroje
|
||||
- Nevyžaduje se žádná instalace klíče API nebo CLI---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | Standard chat (all providers) | All modern tools |
|
||||
| `/v1/responses` | Responses API (OpenAI format) | Codex, agentic workflows |
|
||||
| `/v1/completions` | Legacy text completions | Older tools using `prompt:` |
|
||||
| `/v1/embeddings` | Text embeddings | RAG, search |
|
||||
| `/v1/images/generations` | Image generation | DALL-E, Flux, etc. |
|
||||
| `/v1/audio/speech` | Text-to-speech | ElevenLabs, OpenAI TTS |
|
||||
| `/v1/audio/transcriptions` | Speech-to-text | Deepgram, AssemblyAI |
|
||||
|
||||
---
|
||||
| Koncový bod | Popis | Použití pro |
|
||||
| ------------------------ | --------------------------------------- | ------------------------------------- | --- |
|
||||
| `/v1/chat/completions` | Standardní chat (všichni poskytovatelé) | Všechny moderní nástroje |
|
||||
| `/v1/responses` | Responses API (formát OpenAI) | Codex, agentní pracovní postupy |
|
||||
| `/v1/completions` | Dokončení starších textů | Starší nástroje používající `prompt:` |
|
||||
| `/v1/embeddings` | Vkládání textu | RAG, hledání |
|
||||
| `/v1/images/generations` | Generování obrázku | DALL-E, Flux atd. |
|
||||
| `/v1/audio/řeč` | Převod textu na řeč | ElevenLabs, OpenAI TTS |
|
||||
| `/v1/audio/přepisy` | Převod řeči na text | Deepgram, AssemblyAI | --- |
|
||||
|
||||
## Řešení problémů
|
||||
|
||||
| Error | Cause | Fix |
|
||||
| ------------------------- | ----------------------- | ------------------------------------------ |
|
||||
| `Connection refused` | OmniRoute not running | `pm2 start omniroute` |
|
||||
| `401 Unauthorized` | Wrong API key | Check in `/dashboard/api-manager` |
|
||||
| `No combo configured` | No active routing combo | Set up in `/dashboard/combos` |
|
||||
| `invalid model` | Model not in catalog | Use `auto` or check `/dashboard/providers` |
|
||||
| CLI shows "not installed" | Binary not in PATH | Check `which <command>` |
|
||||
| `kiro-cli: not found` | Not in PATH | `export PATH="$HOME/.local/bin:$PATH"` |
|
||||
|
||||
---
|
||||
| Chyba | Příčina | Opravit |
|
||||
| ---------------------------------- | ----------------------------- | -------------------------------------------------------- | --- |
|
||||
| "Spojení odmítnuto" | OmniRoute neběží | `pm2 start omniroute` |
|
||||
| "401 Neoprávněné" | Špatný klíč API | Zkontrolujte `/dashboard/api-manager` |
|
||||
| `Není nakonfigurováno žádné kombo` | Žádné aktivní směrovací kombo | Nastavit v `/dashboard/combos` |
|
||||
| "neplatný model" | Model není v katalogu | Použijte `auto` nebo zkontrolujte `/dashboard/providers` |
|
||||
| CLI zobrazuje "není nainstalováno" | Binární není v PATH | Zkontrolujte `který <příkaz>` |
|
||||
| `kiro-cli: nenalezeno` | Ne v PATH | `export PATH="$HOME/.local/bin:$PATH"` | --- |
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
|
||||
@@ -1,22 +1,18 @@
|
||||
# omniroute — Codebase Documentation (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../../es/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../../fr/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../../de/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../../it/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../../ru/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../../ja/docs/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../../ko/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../../ar/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [hi](../../hi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../../in/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../../th/docs/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../../vi/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../../id/docs/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../../ms/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../../nl/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../../pl/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../../sv/docs/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../../no/docs/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../../da/docs/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../../fi/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../../pt/docs/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../../ro/docs/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../../hu/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../../bg/docs/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../../sk/docs/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../../he/docs/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../../phi/docs/CODEBASE_DOCUMENTATION.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/CODEBASE_DOCUMENTATION.md) · 🇨🇿 [cs](../../cs/docs/CODEBASE_DOCUMENTATION.md) · 🇹🇷 [tr](../../tr/docs/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
---
|
||||
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
---
|
||||
> Komplexní průvodce proxy routerem**omniroute**pro více poskytovatelů s umělou inteligencí pro začátečníky.---
|
||||
|
||||
## 1. What Is omniroute?
|
||||
|
||||
omniroute is a **proxy router** that sits between AI clients (Claude CLI, Codex, Cursor IDE, etc.) and AI providers (Anthropic, Google, OpenAI, AWS, GitHub, etc.). It solves one big problem:
|
||||
omniroute je**proxy router**, který sedí mezi klienty AI (Claude CLI, Codex, Cursor IDE atd.) a poskytovateli AI (Anthropic, Google, OpenAI, AWS, GitHub atd.). Řeší jeden velký problém:
|
||||
|
||||
> **Different AI clients speak different "languages" (API formats), and different AI providers expect different "languages" too.** omniroute translates between them automatically.
|
||||
> **Různí klienti AI mluví různými „jazyky“ (formáty API) a různí poskytovatelé AI také očekávají různé „jazyky“.**omniroute mezi nimi automaticky překládá.
|
||||
|
||||
Think of it like a universal translator at the United Nations — any delegate can speak any language, and the translator converts it for any other delegate.
|
||||
|
||||
---
|
||||
Představte si to jako univerzální překladatel v Organizaci spojených národů – každý delegát může mluvit jakýmkoli jazykem a překladatel jej převede na jakéhokoli jiného delegáta.---
|
||||
|
||||
## 2. Architecture Overview
|
||||
|
||||
@@ -65,44 +61,43 @@ graph LR
|
||||
|
||||
### Core Principle: Hub-and-Spoke Translation
|
||||
|
||||
All format translation passes through **OpenAI format as the hub**:
|
||||
Veškerý překlad formátu prochází**formátem OpenAI jako centrem**:```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
This means you only need **N translators** (one per format) instead of **N²** (every pair).
|
||||
|
||||
---
|
||||
To znamená, že potřebujete pouze**N překladatelů**(jeden na formát) místo**N²**(každý pár).---
|
||||
|
||||
## 3. Project Structure
|
||||
|
||||
```
|
||||
|
||||
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
|
||||
```
|
||||
├── 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
|
||||
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
@@ -110,18 +105,16 @@ omniroute/
|
||||
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
The **single source of truth** for all provider configuration.
|
||||
**Jediný zdroj pravdy**pro všechny konfigurace poskytovatelů.
|
||||
|
||||
| File | Purpose |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
|
||||
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
|
||||
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
|
||||
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
|
||||
|
||||
#### Credential Loading Flow
|
||||
| Soubor | Účel |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------------ ------------------------------------------------------------------------------------------------------ |
|
||||
| `constants.ts` | Objekt `PROVIDERS` se základními adresami URL, přihlašovacími údaji OAuth (výchozí), záhlavími a výchozími systémovými výzvami pro každého poskytovatele. Definuje také `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` a `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Načte externí přihlašovací údaje z `data/provider-credentials.json` a sloučí je přes pevně zakódované výchozí hodnoty v `PROVIDERS`. Udržuje tajemství mimo kontrolu zdroje při zachování zpětné kompatibility. |
|
||||
| `providerModels.ts` | Centrální registr modelů: mapuje aliasy poskytovatelů → ID modelů. Funkce jako `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | Systémové pokyny vložené do požadavků Codexu (omezení úprav, pravidla karantény, zásady schvalování). |
|
||||
| `defaultThinkingSignature.ts` | Výchozí „myšlenkové“ podpisy pro modely Claude a Gemini. |
|
||||
| `ollamaModels.ts` | Definice schématu pro lokální modely Ollama (název, velikost, rodina, kvantizace). |#### Credential Loading Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -140,24 +133,22 @@ flowchart TD
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Executors (`open-sse/executors/`)
|
||||
|
||||
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
|
||||
|
||||
```mermaid
|
||||
Exekutoři zapouzdřují**logiku specifickou pro poskytovatele**pomocí**Strategy Pattern**. Každý exekutor podle potřeby přepíše základní metody.```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 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()
|
||||
@@ -194,34 +185,31 @@ classDiagram
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| Executor | Provider | Key Specializations |
|
||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Abstract base: URL building, headers, retry logic, credential refresh |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Generic OAuth token refresh for standard providers |
|
||||
| `antigravity.ts` | Google Cloud Code | Project/session ID generation, multi-URL fallback, custom retry parsing from error messages ("reset after 2h7m23s") |
|
||||
| `cursor.ts` | Cursor IDE | **Most complex**: SHA-256 checksum auth, Protobuf request encoding, binary EventStream → SSE response parsing |
|
||||
| `codex.ts` | OpenAI Codex | Injects system instructions, manages thinking levels, removes unsupported parameters |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Custom URL building (`streamGenerateContent`), Google OAuth token refresh |
|
||||
| `github.ts` | GitHub Copilot | Dual token system (GitHub OAuth + Copilot token), VSCode header mimicking |
|
||||
| `kiro.ts` | AWS CodeWhisperer | AWS EventStream binary parsing, AMZN event frames, token estimation |
|
||||
| `index.ts` | — | Factory: maps provider name → executor class, with default fallback |
|
||||
````
|
||||
|
||||
---
|
||||
| Exekutor | Poskytovatel | Klíčové specializace |
|
||||
| ----------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------------------
|
||||
| `base.ts` | — | Abstraktní základ: Tvorba URL, záhlaví, logika opakování, obnovení pověření |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Obecná obnova tokenu OAuth pro standardní poskytovatele |
|
||||
| `antigravity.ts` | Google Cloud Code | Generování ID projektu/relace, záložní více adres URL, vlastní opakování analýzy z chybových zpráv ("resetovat po 2h7m23s") |
|
||||
| `kurzor.ts` | Kurzor IDE |**Nejsložitější**: Ověření kontrolního součtu SHA-256, kódování požadavku Protobuf, binární EventStream → parsování odpovědi SSE |
|
||||
| `codex.ts` | Kodex OpenAI | Vkládá systémové instrukce, řídí úrovně myšlení, odstraňuje nepodporované parametry |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Vytvoření vlastní adresy URL (`streamGenerateContent`), obnovení tokenu Google OAuth |
|
||||
| `github.ts` | GitHub Copilot | Systém dvou tokenů (GitHub OAuth + token Copilot), napodobování hlavičky VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | Binární analýza AWS EventStream, rámce událostí AMZN, odhad tokenu |
|
||||
| `index.ts` | — | Továrna: název poskytovatele map → třída exekutora, s výchozí nouzou |---
|
||||
|
||||
### 4.3 Handlers (`open-sse/handlers/`)
|
||||
|
||||
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
|
||||
**orchestration layer**– koordinuje překlad, provádění, streamování a zpracování chyb.
|
||||
|
||||
| File | Purpose |
|
||||
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | **Central orchestrator** (~600 lines). Handles the complete request lifecycle: format detection → translation → executor dispatch → streaming/non-streaming response → token refresh → error handling → usage logging. |
|
||||
| `responsesHandler.ts` | Adapter for OpenAI's Responses API: converts Responses format → Chat Completions → sends to `chatCore` → converts SSE back to Responses format. |
|
||||
| `embeddings.ts` | Embedding generation handler: resolves embedding model → provider, dispatches to provider API, returns OpenAI-compatible embedding response. Supports 6+ providers. |
|
||||
| `imageGeneration.ts` | Image generation handler: resolves image model → provider, supports OpenAI-compatible, Gemini-image (Antigravity), and fallback (Nebius) modes. Returns base64 or URL images. |
|
||||
|
||||
#### Request Lifecycle (chatCore.ts)
|
||||
| Soubor | Účel |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------- ---------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` |**Centrální orchestrátor**(~600 řádků). Zvládá celý životní cyklus požadavku: detekce formátu → překlad → odeslání exekutora → odezva streamování/nestreamování → obnovení tokenu → zpracování chyb → protokolování využití. |
|
||||
| `responsesHandler.ts` | Adaptér pro OpenAI Responses API: převádí formát odpovědí → Dokončení chatu → odesílá do `chatCore` → převádí SSE zpět na formát odpovědí. |
|
||||
| `embeddings.ts` | Obslužný program generování vkládání: řeší model vkládání → poskytovatel, odesílá rozhraní API poskytovatele, vrací odezvu vkládání kompatibilní s OpenAI. Podporuje 6+ poskytovatelů. |
|
||||
| `imageGeneration.ts` | Ovladač generování obrázků: řeší model obrázku → poskytovatel, podporuje režimy kompatibilní s OpenAI, Gemini-image (Antigravity) a záložní (Nebius). Vrátí base64 nebo obrázky URL. |#### Request Lifecycle (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -256,30 +244,28 @@ sequenceDiagram
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
````
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Services (`open-sse/services/`)
|
||||
|
||||
Business logic that supports the handlers and executors.
|
||||
|
||||
| File | Purpose |
|
||||
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
|
||||
| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
|
||||
| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). |
|
||||
| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
|
||||
| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
|
||||
| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
|
||||
| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
|
||||
| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
|
||||
| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
|
||||
| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
|
||||
| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
|
||||
| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
|
||||
| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
|
||||
| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |
|
||||
| Obchodní logika, která podporuje handlery a exekutory. | File | Purpose |
|
||||
| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- |
|
||||
| `provider.ts` | **Format detection** (`detectFormat`): analyzes request body structure to identify Claude/OpenAI/Gemini/Antigravity/Responses formats (includes `max_tokens` heuristic for Claude). Also: URL building, header building, thinking config normalization. Supports `openai-compatible-*` and `anthropic-compatible-*` dynamic providers. |
|
||||
| `model.ts` | Model string parsing (`claude/model-name` → `{provider: "claude", model: "model-name"}`), alias resolution with collision detection, input sanitization (rejects path traversal/control chars), and model info resolution with async alias getter support. |
|
||||
| `accountFallback.ts` | Rate-limit handling: exponential backoff (1s → 2s → 4s → max 2min), account cooldown management, error classification (which errors trigger fallback vs. not). |
|
||||
| `tokenRefresh.ts` | OAuth token refresh for **every provider**: Google (Gemini, Antigravity), Claude, Codex, Qwen, Qoder, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Includes in-flight promise deduplication cache and retry with exponential backoff. |
|
||||
| `combo.ts` | **Combo models**: chains of fallback models. If model A fails with a fallback-eligible error, try model B, then C, etc. Returns actual upstream status codes. |
|
||||
| `usage.ts` | Fetches quota/usage data from provider APIs (GitHub Copilot quotas, Antigravity model quotas, Codex rate limits, Kiro usage breakdowns, Claude settings). |
|
||||
| `accountSelector.ts` | Smart account selection with scoring algorithm: considers priority, health status, round-robin position, and cooldown state to pick the optimal account for each request. |
|
||||
| `contextManager.ts` | Request context lifecycle management: creates and tracks per-request context objects with metadata (request ID, timestamps, provider info) for debugging and logging. |
|
||||
| `ipFilter.ts` | IP-based access control: supports allowlist and blocklist modes. Validates client IP against configured rules before processing API requests. |
|
||||
| `sessionManager.ts` | Session tracking with client fingerprinting: tracks active sessions using hashed client identifiers, monitors request counts, and provides session metrics. |
|
||||
| `signatureCache.ts` | Request signature-based deduplication cache: prevents duplicate requests by caching recent request signatures and returning cached responses for identical requests within a time window. |
|
||||
| `systemPrompt.ts` | Global system prompt injection: prepends or appends a configurable system prompt to all requests, with per-provider compatibility handling. |
|
||||
| `thinkingBudget.ts` | Reasoning token budget management: supports passthrough, auto (strip thinking config), custom (fixed budget), and adaptive (complexity-scaled) modes for controlling thinking/reasoning tokens. |
|
||||
| `wildcardRouter.ts` | Wildcard model pattern routing: resolves wildcard patterns (e.g., `*/claude-*`) to concrete provider/model pairs based on availability and priority. |
|
||||
|
||||
#### Token Refresh Deduplication
|
||||
|
||||
@@ -348,9 +334,7 @@ flowchart LR
|
||||
|
||||
### 4.5 Translator (`open-sse/translator/`)
|
||||
|
||||
The **format translation engine** using a self-registering plugin system.
|
||||
|
||||
#### Architektura
|
||||
**Formátový překladový stroj**využívající samoregistrující se zásuvný systém.#### Architektura
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
@@ -376,15 +360,13 @@ graph TD
|
||||
end
|
||||
```
|
||||
|
||||
| Directory | Files | Description |
|
||||
| ------------ | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 translators | Convert request bodies between formats. Each file self-registers via `register(from, to, fn)` on import. |
|
||||
| `response/` | 7 translators | Convert streaming response chunks between formats. Handles SSE event types, thinking blocks, tool calls. |
|
||||
| `helpers/` | 6 helpers | Shared utilities: `claudeHelper` (system prompt extraction, thinking config), `geminiHelper` (parts/contents mapping), `openaiHelper` (format filtering), `toolCallHelper` (ID generation, missing response injection), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Translation engine: `translateRequest()`, `translateResponse()`, state management, registry. |
|
||||
| `formats.ts` | — | Format constants: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
|
||||
#### Key Design: Self-Registering Plugins
|
||||
| Adresář | Soubory | Popis |
|
||||
| ------------ | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
||||
| `požadavek/` | 8 překladatelů | Převeďte těla požadavků mezi formáty. Každý soubor se při importu sám zaregistruje pomocí `register(from, to, fn)`. |
|
||||
| `reakce/` | 7 překladatelů | Převádějte bloky odezvy streamování mezi formáty. Zvládá typy událostí SSE, bloky myšlení, volání nástrojů. |
|
||||
| `pomocníci/` | 6 pomocníků | Sdílené nástroje: `claudeHelper` (extrakce systémového promptu, konfigurace myšlení), `geminiHelper` (mapování částí/obsahu), `openaiHelper` (filtrování formátů), `toolCallHelper` (generování ID, chybějící vložení odpovědi), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Překladový stroj: `translateRequest()`, `translateResponse()`, správa stavu, registr. |
|
||||
| `formats.ts` | — | Formátové konstanty: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. | #### Key Design: Self-Registering Plugins |
|
||||
|
||||
```javascript
|
||||
// Each translator file calls register() on import:
|
||||
@@ -399,17 +381,15 @@ import "./request/claude-to-openai.js"; // ← self-registers
|
||||
|
||||
### 4.6 Utils (`open-sse/utils/`)
|
||||
|
||||
| File | Purpose |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `error.ts` | Error response building (OpenAI-compatible format), upstream error parsing, Antigravity retry-time extraction from error messages, SSE error streaming. |
|
||||
| `stream.ts` | **SSE Transform Stream** — the core streaming pipeline. Two modes: `TRANSLATE` (full format translation) and `PASSTHROUGH` (normalize + extract usage). Handles chunk buffering, usage estimation, content length tracking. Per-stream encoder/decoder instances avoid shared state. |
|
||||
| `streamHelpers.ts` | Low-level SSE utilities: `parseSSELine` (whitespace-tolerant), `hasValuableContent` (filters empty chunks for OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (format-aware SSE serialization with `perf_metrics` cleanup). |
|
||||
| `usageTracking.ts` | Token usage extraction from any format (Claude/OpenAI/Gemini/Responses), estimation with separate tool/message char-per-token ratios, buffer addition (2000 tokens safety margin), format-specific field filtering, console logging with ANSI colors. |
|
||||
| `requestLogger.ts` | File-based request logging (opt-in via `ENABLE_REQUEST_LOGS=true`). Creates session folders with numbered files: `1_req_client.json` → `7_res_client.txt`. All I/O is async (fire-and-forget). Masks sensitive headers. |
|
||||
| `bypassHandler.ts` | Intercepts specific patterns from Claude CLI (title extraction, warmup, count) and returns fake responses without calling any provider. Supports both streaming and non-streaming. Intentionally limited to Claude CLI scope. |
|
||||
| `networkProxy.ts` | Resolves outbound proxy URL for a given provider with precedence: provider-specific config → global config → environment variables (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Supports `NO_PROXY` exclusions. Caches config for 30s. |
|
||||
|
||||
#### SSE Streaming Pipeline
|
||||
| Soubor | Účel |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
|
||||
| `error.ts` | Vytváření chybové odezvy (formát kompatibilní s OpenAI), analýza chyb upstream, extrakce opakování antigravity z chybových zpráv, streamování chyb SSE. |
|
||||
| `stream.ts` | **SSE Transform Stream**– hlavní streamovací kanál. Dva režimy: `TRANSLATE` (překlad plného formátu) a `PASSTHROUGH` (normalizovat + extrahovat použití). Zvládá ukládání do vyrovnávací paměti, odhad využití, sledování délky obsahu. Instance kodéru/dekodéru pro jednotlivé proudy se vyhýbají sdílenému stavu. |
|
||||
| `streamHelpers.ts` | Nízkoúrovňové nástroje SSE: `parseSSELine` (tolerující mezery), `hasValuableContent` (filtruje prázdné bloky pro OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (serializace SSE s ohledem na formát s vyčištěním `perf_metrics`). |
|
||||
| `usageTracking.ts` | Extrakce využití tokenů z libovolného formátu (Claude/OpenAI/Gemini/Responses), odhad pomocí samostatných poměrů znaků na token nástroje/zprávy, přidání do vyrovnávací paměti (bezpečnostní rezerva 2000 tokenů), filtrování polí podle formátu, protokolování konzoly pomocí barev ANSI. |
|
||||
| `requestLogger.ts` | Protokolování požadavků na základě souborů (přihlášení přes `ENABLE_REQUEST_LOGS=true`). Vytváří složky relací s číslovanými soubory: `1_req_client.json` → `7_res_client.txt`. Všechny I/O jsou asynchronní (fire-and-forget). Maskuje citlivé hlavičky. |
|
||||
| `bypassHandler.ts` | Zachycuje specifické vzory z Claude CLI (extrakce titulů, zahřívání, počet) a vrací falešné odpovědi bez volání jakéhokoli poskytovatele. Podporuje streamování i nestreamování. Záměrně omezeno na rozsah Claude CLI. |
|
||||
| `networkProxy.ts` | Vyřeší odchozí adresu URL proxy pro daného poskytovatele s prioritou: konfigurace specifická pro poskytovatele → globální konfigurace → proměnné prostředí (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Podporuje výjimky `NO_PROXY`. Konfiguraci mezipaměti po dobu 30 s. | #### SSE Streaming Pipeline |
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -451,103 +431,81 @@ logs/
|
||||
|
||||
### 4.7 Application Layer (`src/`)
|
||||
|
||||
| Directory | Purpose |
|
||||
| ------------- | ---------------------------------------------------------------------- |
|
||||
| `src/app/` | Web UI, API routes, Express middleware, OAuth callback handlers |
|
||||
| `src/lib/` | Database access (`localDb.ts`, `usageDb.ts`), authentication, shared |
|
||||
| `src/mitm/` | Man-in-the-middle proxy utilities for intercepting provider traffic |
|
||||
| `src/models/` | Database model definitions |
|
||||
| `src/shared/` | Wrappers around open-sse functions (provider, stream, error, etc.) |
|
||||
| `src/sse/` | SSE endpoint handlers that wire the open-sse library to Express routes |
|
||||
| `src/store/` | Application state management |
|
||||
| Adresář | Účel |
|
||||
| ------------- | ---------------------------------------------------------------------------------------------------- | ----------------------- |
|
||||
| `src/app/` | Webové uživatelské rozhraní, trasy API, expresní middleware, obslužné nástroje zpětného volání OAuth |
|
||||
| `src/lib/` | Přístup k databázi (`localDb.ts`, `usageDb.ts`), ověřování, sdílené |
|
||||
| `src/mitm/` | Man-in-the-middle proxy nástroje pro zachycení provozu poskytovatele |
|
||||
| `src/models/` | Definice databázových modelů |
|
||||
| `src/shared/` | Obaly kolem funkcí open-sse (poskytovatel, stream, chyba atd.) |
|
||||
| `src/sse/` | Obslužné rutiny koncových bodů SSE, které propojují knihovnu open-sse s cestami Express |
|
||||
| `src/store/` | Správa stavu aplikace | #### Notable API Routes |
|
||||
|
||||
#### Notable API Routes
|
||||
|
||||
| Route | Methods | Purpose |
|
||||
| --------------------------------------------- | --------------- | ------------------------------------------------------------------------------------- |
|
||||
| `/api/provider-models` | GET/POST/DELETE | CRUD for custom models per provider |
|
||||
| `/api/models/catalog` | GET | Aggregated catalog of all models (chat, embedding, image, custom) grouped by provider |
|
||||
| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchical outbound proxy configuration (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | POST | Validates proxy connectivity and returns public IP/latency |
|
||||
| `/v1/providers/[provider]/chat/completions` | POST | Dedicated per-provider chat completions with model validation |
|
||||
| `/v1/providers/[provider]/embeddings` | POST | Dedicated per-provider embeddings with model validation |
|
||||
| `/v1/providers/[provider]/images/generations` | POST | Dedicated per-provider image generation with model validation |
|
||||
| `/api/settings/ip-filter` | GET/PUT | IP allowlist/blocklist management |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Reasoning token budget configuration (passthrough/auto/custom/adaptive) |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Global system prompt injection for all requests |
|
||||
| `/api/sessions` | GET | Active session tracking and metrics |
|
||||
| `/api/rate-limits` | GET | Per-account rate limit status |
|
||||
|
||||
---
|
||||
| Trasa | Metody | Účel |
|
||||
| ------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------- | --- |
|
||||
| `/api/provider-models` | ZÍSKAT/POSLAT/SMAZAT | CRUD pro vlastní modely na poskytovatele |
|
||||
| `/api/models/catalog` | ZÍSKEJTE | Souhrnný katalog všech modelů (chat, embedding, image, custom) seskupený podle poskytovatele |
|
||||
| `/api/settings/proxy` | GET/PUT/DELETE | Hierarchická konfigurace odchozího proxy (`globální/poskytovatelé/komba/klíče`) |
|
||||
| `/api/settings/proxy/test` | PŘÍSPĚVEK | Ověřuje připojení proxy a vrací veřejnou IP/latenci |
|
||||
| `/v1/providers/[poskytovatel]/chat/completions` | PŘÍSPĚVEK | Vyhrazená dokončení chatu na poskytovatele s ověřením modelu |
|
||||
| `/v1/providers/[poskytovatel]/embeddings` | PŘÍSPĚVEK | Vyhrazené vložení pro poskytovatele s ověřením modelu |
|
||||
| `/v1/providers/[poskytovatel]/images/generations` | PŘÍSPĚVEK | Vyhrazené generování obrazu podle poskytovatele s ověřením modelu |
|
||||
| `/api/settings/ip-filter` | GET/PUT | Správa seznamu povolených/blokovaných IP |
|
||||
| `/api/settings/thinking-budget` | GET/PUT | Konfigurace rozpočtu tokenu odůvodnění (průchozí/automatické/vlastní/adaptivní) |
|
||||
| `/api/settings/system-prompt` | GET/PUT | Globální systémová okamžitá injekce pro všechny požadavky |
|
||||
| `/api/sessions` | ZÍSKEJTE | Sledování aktivní relace a metriky |
|
||||
| `/api/rate-limits` | ZÍSKEJTE | Stav limitu sazby na účet | --- |
|
||||
|
||||
## 5. Key Design Patterns
|
||||
|
||||
### 5.1 Hub-and-Spoke Translation
|
||||
|
||||
All formats translate through **OpenAI format as the hub**. Adding a new provider only requires writing **one pair** of translators (to/from OpenAI), not N pairs.
|
||||
Všechny formáty se překládají prostřednictvím**formátu OpenAI jako centra**. Přidání nového poskytovatele vyžaduje pouze napsat**jeden pár**překladatelů (do/z OpenAI), nikoli N párů.### 5.2 Executor Strategy Pattern
|
||||
|
||||
### 5.2 Executor Strategy Pattern
|
||||
Každý poskytovatel má vyhrazenou třídu exekutorů, která dědí z `BaseExecutor`. Továrna v `executors/index.ts` vybere ten správný za běhu.### 5.3 Self-Registering Plugin System
|
||||
|
||||
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
|
||||
Moduly překladatele se při importu zaregistrují pomocí `register()`. Přidání nového překladače znamená pouze vytvoření souboru a jeho import.### 5.4 Account Fallback with Exponential Backoff
|
||||
|
||||
### 5.3 Self-Registering Plugin System
|
||||
Když poskytovatel vrátí 429/401/500, systém se může přepnout na další účet a použít exponenciální cooldowny (1s → 2s → 4s → max 2min).### 5.5 Combo Model Chains
|
||||
|
||||
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
|
||||
"Combo" seskupuje více řetězců "poskytovatel/model". Pokud první selže, automaticky se vraťte k dalšímu.### 5.6 Stateful Streaming Translation
|
||||
|
||||
### 5.4 Account Fallback with Exponential Backoff
|
||||
Překlad odezvy udržuje stav napříč bloky SSE (sledování bloků myšlení, akumulace volání nástrojů, indexování bloků obsahu) prostřednictvím mechanismu `initState()`.### 5.7 Usage Safety Buffer
|
||||
|
||||
When a provider returns 429/401/500, the system can switch to the next account, applying exponential cooldowns (1s → 2s → 4s → max 2min).
|
||||
|
||||
### 5.5 Combo Model Chains
|
||||
|
||||
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
|
||||
|
||||
### 5.6 Stateful Streaming Translation
|
||||
|
||||
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
|
||||
|
||||
### 5.7 Usage Safety Buffer
|
||||
|
||||
A 2000-token buffer is added to reported usage to prevent clients from hitting context window limits due to overhead from system prompts and format translation.
|
||||
|
||||
---
|
||||
K nahlášenému využití je přidána vyrovnávací paměť s 2000 tokeny, aby se klientům zabránilo narazit na limity kontextového okna kvůli režii systémových výzev a překladu formátu.---
|
||||
|
||||
## 6. Supported Formats
|
||||
|
||||
| Format | Direction | Identifier |
|
||||
| ----------------------- | --------------- | ------------------ |
|
||||
| OpenAI Chat Completions | source + target | `openai` |
|
||||
| OpenAI Responses API | source + target | `openai-responses` |
|
||||
| Anthropic Claude | source + target | `claude` |
|
||||
| Google Gemini | source + target | `gemini` |
|
||||
| Google Gemini CLI | target only | `gemini-cli` |
|
||||
| Antigravity | source + target | `antigravity` |
|
||||
| AWS Kiro | target only | `kiro` |
|
||||
| Cursor | target only | `cursor` |
|
||||
|
||||
---
|
||||
| Formát | Směr | Identifikátor |
|
||||
| ---------------------- | ----------- | ----------------- | --- |
|
||||
| Dokončení chatu OpenAI | zdroj + cíl | "openai" |
|
||||
| OpenAI Responses API | zdroj + cíl | "openai-odpovědi" |
|
||||
| Antropický Claude | zdroj + cíl | "claude" |
|
||||
| Google Gemini | zdroj + cíl | "blíženci" |
|
||||
| Google Gemini CLI | pouze cíl | `gemini-cli` |
|
||||
| Antigravitace | zdroj + cíl | "antigravitace" |
|
||||
| AWS Kiro | pouze cíl | "kiro" |
|
||||
| Kurzor | pouze cíl | "kurzor" | --- |
|
||||
|
||||
## 7. Supported Providers
|
||||
|
||||
| Provider | Auth Method | Executor | Key Notes |
|
||||
| ------------------------ | ---------------------- | ----------- | --------------------------------------------- |
|
||||
| Anthropic Claude | API key or OAuth | Default | Uses `x-api-key` header |
|
||||
| Google Gemini | API key or OAuth | Default | Uses `x-goog-api-key` header |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Uses `streamGenerateContent` endpoint |
|
||||
| Antigravity | OAuth | Antigravity | Multi-URL fallback, custom retry parsing |
|
||||
| OpenAI | API key | Default | Standard Bearer auth |
|
||||
| Codex | OAuth | Codex | Injects system instructions, manages thinking |
|
||||
| GitHub Copilot | OAuth + Copilot token | Github | Dual token, VSCode header mimicking |
|
||||
| Kiro (AWS) | AWS SSO OIDC or Social | Kiro | Binary EventStream parsing |
|
||||
| Cursor IDE | Checksum auth | Cursor | Protobuf encoding, SHA-256 checksums |
|
||||
| Qwen | OAuth | Default | Standard auth |
|
||||
| Qoder | OAuth (Basic + Bearer) | Default | Dual auth header |
|
||||
| OpenRouter | API key | Default | Standard Bearer auth |
|
||||
| GLM, Kimi, MiniMax | API key | Default | Claude-compatible, use `x-api-key` |
|
||||
| `openai-compatible-*` | API key | Default | Dynamic: any OpenAI-compatible endpoint |
|
||||
| `anthropic-compatible-*` | API key | Default | Dynamic: any Claude-compatible endpoint |
|
||||
|
||||
---
|
||||
| Poskytovatel | Metoda ověřování | Exekutor | Klíčové poznámky |
|
||||
| --------------------------- | ------------------------------- | ------------- | ----------------------------------------------------- | --- |
|
||||
| Antropický Claude | Klíč API nebo OAuth | Výchozí | Používá hlavičku `x-api-key` |
|
||||
| Google Gemini | Klíč API nebo OAuth | Výchozí | Používá záhlaví `x-goog-api-key` |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Používá koncový bod `streamGenerateContent` |
|
||||
| Antigravitace | OAuth | Antigravitace | Záložní více adres URL, vlastní opakování analýzy |
|
||||
| OpenAI | API klíč | Výchozí | Standardní ověření nositele |
|
||||
| Codex | OAuth | Codex | Vkládá systémové pokyny, řídí myšlení |
|
||||
| GitHub Copilot | OAuth + token Copilot | Github | Duální token, hlavička VSCode napodobující |
|
||||
| Kiro (AWS) | AWS SSO OIDC nebo sociální sítě | Kiro | Analýza binárního EventStreamu |
|
||||
| Kurzor IDE | Ověření kontrolního součtu | Kurzor | Kódování Protobuf, kontrolní součty SHA-256 |
|
||||
| Qwen | OAuth | Výchozí | Standardní autentizace |
|
||||
| Qoder | OAuth (základní + nosič) | Výchozí | Dual auth header |
|
||||
| OpenRouter | API klíč | Výchozí | Standardní ověření nositele |
|
||||
| GLM, Kimi, MiniMax | API klíč | Výchozí | Claude kompatibilní, použijte `x-api-key` |
|
||||
| `openai-compatible-*` | API klíč | Výchozí | Dynamický: jakýkoli koncový bod kompatibilní s OpenAI |
|
||||
| `antropický-kompatibilní-*` | API klíč | Výchozí | Dynamický: jakýkoli koncový bod kompatibilní s Claude | --- |
|
||||
|
||||
## 8. Data Flow Summary
|
||||
|
||||
|
||||
@@ -1,158 +1,132 @@
|
||||
# Test Coverage Plan (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/COVERAGE_PLAN.md) · 🇪🇸 [es](../../es/docs/COVERAGE_PLAN.md) · 🇫🇷 [fr](../../fr/docs/COVERAGE_PLAN.md) · 🇩🇪 [de](../../de/docs/COVERAGE_PLAN.md) · 🇮🇹 [it](../../it/docs/COVERAGE_PLAN.md) · 🇷🇺 [ru](../../ru/docs/COVERAGE_PLAN.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/COVERAGE_PLAN.md) · 🇯🇵 [ja](../../ja/docs/COVERAGE_PLAN.md) · 🇰🇷 [ko](../../ko/docs/COVERAGE_PLAN.md) · 🇸🇦 [ar](../../ar/docs/COVERAGE_PLAN.md) · 🇮🇳 [hi](../../hi/docs/COVERAGE_PLAN.md) · 🇮🇳 [in](../../in/docs/COVERAGE_PLAN.md) · 🇹🇭 [th](../../th/docs/COVERAGE_PLAN.md) · 🇻🇳 [vi](../../vi/docs/COVERAGE_PLAN.md) · 🇮🇩 [id](../../id/docs/COVERAGE_PLAN.md) · 🇲🇾 [ms](../../ms/docs/COVERAGE_PLAN.md) · 🇳🇱 [nl](../../nl/docs/COVERAGE_PLAN.md) · 🇵🇱 [pl](../../pl/docs/COVERAGE_PLAN.md) · 🇸🇪 [sv](../../sv/docs/COVERAGE_PLAN.md) · 🇳🇴 [no](../../no/docs/COVERAGE_PLAN.md) · 🇩🇰 [da](../../da/docs/COVERAGE_PLAN.md) · 🇫🇮 [fi](../../fi/docs/COVERAGE_PLAN.md) · 🇵🇹 [pt](../../pt/docs/COVERAGE_PLAN.md) · 🇷🇴 [ro](../../ro/docs/COVERAGE_PLAN.md) · 🇭🇺 [hu](../../hu/docs/COVERAGE_PLAN.md) · 🇧🇬 [bg](../../bg/docs/COVERAGE_PLAN.md) · 🇸🇰 [sk](../../sk/docs/COVERAGE_PLAN.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/COVERAGE_PLAN.md) · 🇮🇱 [he](../../he/docs/COVERAGE_PLAN.md) · 🇵🇭 [phi](../../phi/docs/COVERAGE_PLAN.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/COVERAGE_PLAN.md) · 🇨🇿 [cs](../../cs/docs/COVERAGE_PLAN.md) · 🇹🇷 [tr](../../tr/docs/COVERAGE_PLAN.md)
|
||||
|
||||
---
|
||||
|
||||
Last updated: 2026-03-28
|
||||
Poslední aktualizace: 28. 3. 2026## Baseline
|
||||
|
||||
## Baseline
|
||||
Existuje několik čísel pokrytí v závislosti na způsobu výpočtu zprávy. Pro plánování je užitečný pouze jeden z nich.
|
||||
|
||||
There are multiple coverage numbers depending on how the report is computed. For planning, only one of them is useful.
|
||||
| Metrické | Rozsah | Výpisy / řádky | Větve | Funkce | Poznámky |
|
||||
| ----------------- | ------------------------------------------------- | -------------: | ------: | ------: | ---------------------------------------------------------- |
|
||||
| Dědictví | Starý `npm run test:coverage` | 79,42 % | 75,15 % | 67,94 % | Nafouknutý: počítá testovací soubory a vylučuje `open-sse` |
|
||||
| Diagnostické | Pouze zdroj, s výjimkou testů a bez "open-sse" | 68,16 % | 63,55 % | 64,06 % | Užitečné pouze k izolaci `src/**` |
|
||||
| Doporučený základ | Pouze zdroj, s výjimkou testů a včetně „open-sse“ | 56,95 % | 66,05 % | 57,80 % | Toto je základní plán pro celý projekt ke zlepšení |
|
||||
|
||||
| Metric | Scope | Statements / Lines | Branches | Functions | Notes |
|
||||
| -------------------- | ----------------------------------------------------- | -----------------: | -------: | --------: | --------------------------------------------------- |
|
||||
| Legacy | Old `npm run test:coverage` | 79.42% | 75.15% | 67.94% | Inflated: counts test files and excludes `open-sse` |
|
||||
| Diagnostic | Source-only, excluding tests and excluding `open-sse` | 68.16% | 63.55% | 64.06% | Useful only to isolate `src/**` |
|
||||
| Recommended baseline | Source-only, excluding tests and including `open-sse` | 56.95% | 66.05% | 57.80% | This is the project-wide baseline to improve |
|
||||
Doporučený základ je počet, podle kterého se má optimalizovat.## Rules
|
||||
|
||||
The recommended baseline is the number to optimize against.
|
||||
|
||||
## Rules
|
||||
|
||||
- Coverage targets apply to source files, not to `tests/**`.
|
||||
- `open-sse/**` is part of the product and must remain in scope.
|
||||
- New code should not reduce coverage in touched areas.
|
||||
- Prefer testing behavior and branch outcomes over implementation details.
|
||||
- Prefer temp SQLite databases and small fixtures over broad mocks for `src/lib/db/**`.
|
||||
|
||||
## Current command set
|
||||
- Cíle pokrytí se vztahují na zdrojové soubory, nikoli na `tests/**`.
|
||||
- `open-sse/**` je součástí produktu a musí zůstat v rozsahu.
|
||||
- Nový kód by neměl snižovat pokrytí v dotčených oblastech.
|
||||
- Upřednostňujte testovací chování a výsledky větve před detaily implementace.
|
||||
- Preferujte dočasné databáze SQLite a malá příslušenství před širokými simulacemi pro `src/lib/db/**`.## Current command set
|
||||
|
||||
- `npm run test:coverage`
|
||||
- Main source coverage gate for the unit test suite
|
||||
- Generates `text-summary`, `html`, `json-summary`, and `lcov`
|
||||
- `npm run coverage:report`
|
||||
- Detailed file-by-file report from the latest run
|
||||
- Hlavní brána pokrytí zdroje pro sadu testů jednotek
|
||||
- Generuje `text-summary`, `html`, `json-summary` a `lcov`
|
||||
- `Pokrytí běhu npm: zpráva`
|
||||
- Podrobná zpráva po jednotlivých souborech z posledního spuštění
|
||||
- `npm run test:coverage:legacy`
|
||||
- Historical comparison only
|
||||
- Pouze historické srovnání## Milestones
|
||||
|
||||
## Milestones
|
||||
| Fáze | Cíl | Zaměření |
|
||||
| ------ | ------------------: | --------------------------------------------------------- |
|
||||
| Fáze 1 | 60 % výpisů / řádků | Rychlé výhry a pokrytí nástrojem s nízkým rizikem |
|
||||
| Fáze 2 | 65 % výpisů / řádků | DB a základy trasy |
|
||||
| Fáze 3 | 70 % výpisů / řádků | Ověření poskytovatele a analýzy využití |
|
||||
| Fáze 4 | 75 % výpisů / řádků | `open-sse` překladatelé a pomocníci |
|
||||
| Fáze 5 | 80 % výpisů / řádků | `open-sse` handlery a exekutorské pobočky |
|
||||
| Fáze 6 | 85 % výpisů / řádků | Případy tvrdšího okraje, dluh na pobočkách, regresní sady |
|
||||
| Fáze 7 | 90 % výpisů / řádků | Konečné zametání, uzavření mezery, přísná ráčna |
|
||||
|
||||
| Phase | Target | Focus |
|
||||
| ------- | ---------------------: | ------------------------------------------------- |
|
||||
| Phase 1 | 60% statements / lines | Quick wins and low-risk utility coverage |
|
||||
| Phase 2 | 65% statements / lines | DB and route foundations |
|
||||
| Phase 3 | 70% statements / lines | Provider validation and usage analytics |
|
||||
| Phase 4 | 75% statements / lines | `open-sse` translators and helpers |
|
||||
| Phase 5 | 80% statements / lines | `open-sse` handlers and executor branches |
|
||||
| Phase 6 | 85% statements / lines | Harder edge cases, branch debt, regression suites |
|
||||
| Phase 7 | 90% statements / lines | Final sweep, gap closure, strict ratchet |
|
||||
Větve a funkce by měly s každou fází stoupat, ale primárním pevným cílem jsou příkazy/řádky.## Priority hotspots
|
||||
|
||||
Branches and functions should ratchet upward with each phase, but the primary hard target is statements / lines.
|
||||
Tyto soubory nebo oblasti nabízejí nejlepší návratnost pro další fáze:
|
||||
|
||||
## Priority hotspots
|
||||
|
||||
These files or areas offer the best return for the next phases:
|
||||
|
||||
1. `open-sse/handlers`
|
||||
- `chatCore.ts` at 7.57%
|
||||
- Overall directory at 29.07%
|
||||
1. „open-sse/handlers“.
|
||||
- `chatCore.ts` na 7,57 %
|
||||
- Celkový adresář na 29,07 %
|
||||
2. `open-sse/translator/request`
|
||||
- Overall directory at 36.39%
|
||||
- Many translators are still near single-digit coverage
|
||||
- Celkový adresář na 36,39 %
|
||||
- Mnoho překladatelů se stále blíží jednocifernému pokrytí
|
||||
3. `open-sse/translator/response`
|
||||
- Overall directory at 8.07%
|
||||
- Celkový adresář na 8,07 %
|
||||
4. `open-sse/executors`
|
||||
- Overall directory at 36.62%
|
||||
- Celkový adresář na 36,62 %
|
||||
5. `src/lib/db`
|
||||
- `models.ts` at 20.66%
|
||||
- `registeredKeys.ts` at 34.46%
|
||||
- `modelComboMappings.ts` at 36.25%
|
||||
- `settings.ts` at 46.40%
|
||||
- `webhooks.ts` at 33.33%
|
||||
- `models.ts` na 20,66 %
|
||||
- `registeredKeys.ts` na 34,46 %
|
||||
- `modelComboMappings.ts` na 36,25 %
|
||||
- `settings.ts` na 46,40 %
|
||||
- `webhooks.ts` na 33,33 %
|
||||
6. `src/lib/usage`
|
||||
- `usageHistory.ts` at 21.12%
|
||||
- `usageStats.ts` at 9.56%
|
||||
- `costCalculator.ts` at 30.00%
|
||||
- `usageHistory.ts` na 21,12 %
|
||||
- `usageStats.ts` na 9,56 %
|
||||
- `costCalculator.ts` na 30,00 %
|
||||
7. `src/lib/providers`
|
||||
- `validation.ts` at 41.16%
|
||||
8. Low-risk utility and API files for early gains
|
||||
- `validace.ts` na 41,16 %
|
||||
8. Nízkorizikový nástroj a soubory API pro počáteční zisky
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
|
||||
## Execution checklist
|
||||
- `src/app/api/providers/[id]/models/route.ts`## Execution checklist
|
||||
|
||||
### Phase 1: 56.95% -> 60%
|
||||
|
||||
- [x] Fix coverage metric so it reflects source code instead of test files
|
||||
- [x] Keep a legacy coverage script for comparison
|
||||
- [x] Record the baseline and hotspots in-repo
|
||||
- [ ] Add focused tests for low-risk utilities:
|
||||
- [x] Opravte metriku pokrytí, aby odrážela zdrojový kód namísto testovacích souborů
|
||||
- [x] Uschovejte si starší skript pokrytí pro srovnání
|
||||
- [x] Zaznamenejte základní linii a aktivní body v repo
|
||||
- [ ] Přidejte cílené testy pro nástroje s nízkým rizikem:
|
||||
- `src/shared/utils/upstreamError.ts`
|
||||
- `src/shared/utils/fetchTimeout.ts`
|
||||
- `src/lib/api/errorResponse.ts`
|
||||
- `src/shared/utils/apiAuth.ts`
|
||||
- `src/lib/display/names.ts`
|
||||
- [ ] Add route tests for:
|
||||
- [ ] Přidat testy trasy pro:
|
||||
- `src/app/api/settings/require-login/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`
|
||||
- `src/app/api/providers/[id]/models/route.ts`### Phase 2: 60% -> 65%
|
||||
|
||||
### Phase 2: 60% -> 65%
|
||||
|
||||
- [ ] Add DB-backed tests for:
|
||||
- [ ] Přidat testy podporované DB pro:
|
||||
- `src/lib/db/modelComboMappings.ts`
|
||||
- `src/lib/db/settings.ts`
|
||||
- `src/lib/db/registeredKeys.ts`
|
||||
- [ ] Cover branch behavior in:
|
||||
- [ ] Pokrýt chování větve v:
|
||||
- `src/lib/providers/validation.ts`
|
||||
- `src/app/api/v1/embeddings/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`
|
||||
- `src/app/api/v1/moderations/route.ts`### Phase 3: 65% -> 70%
|
||||
|
||||
### Phase 3: 65% -> 70%
|
||||
|
||||
- [ ] Add usage analytics tests for:
|
||||
- [ ] Přidat analytické testy využití pro:
|
||||
- `src/lib/usage/usageHistory.ts`
|
||||
- `src/lib/usage/usageStats.ts`
|
||||
- `src/lib/usage/costCalculator.ts`
|
||||
- [ ] Expand route coverage for proxy management and settings branches
|
||||
- [ ] Rozšiřte pokrytí trasy pro větve správy proxy a nastavení### Phase 4: 70% -> 75%
|
||||
|
||||
### Phase 4: 70% -> 75%
|
||||
|
||||
- [ ] Cover translator helpers and central translation paths:
|
||||
- [ ] Pokrývají pomocníci překladatele a centrální cesty překladu:
|
||||
- `open-sse/translator/index.ts`
|
||||
- `open-sse/translator/helpers/*`
|
||||
- `open-sse/translator/request/*`
|
||||
- `open-sse/translator/response/*`
|
||||
- `open-sse/translator/response/*`### Phase 5: 75% -> 80%
|
||||
|
||||
### Phase 5: 75% -> 80%
|
||||
|
||||
- [ ] Add handler-level tests for:
|
||||
- [ ] Přidat testy na úrovni obsluhy pro:
|
||||
- `open-sse/handlers/chatCore.ts`
|
||||
- `open-sse/handlers/responsesHandler.js`
|
||||
- `open-sse/handlers/imageGeneration.js`
|
||||
- `open-sse/handlers/embeddings.js`
|
||||
- [ ] Add executor branch coverage for provider-specific auth, retries, and endpoint overrides
|
||||
- [ ] Přidejte pokrytí větve exekutora pro ověření, opakování a přepsání koncového bodu specifické pro poskytovatele### Phase 6: 80% -> 85%
|
||||
|
||||
### Phase 6: 80% -> 85%
|
||||
- [ ] Sloučit více sad okrajových případů do hlavní cesty pokrytí
|
||||
- [ ] Zvyšte pokrytí funkcí pro moduly DB se slabým pokrytím konstruktorem/pomocníkem
|
||||
- [ ] Zavřete mezery mezi větvemi v souborech `settings.ts`, `registeredKeys.ts`, `validation.ts` a pomocníkech překladače### Phase 7: 85% -> 90%
|
||||
|
||||
- [ ] Merge more edge-case suites into the main coverage path
|
||||
- [ ] Increase function coverage for DB modules with weak constructor/helper coverage
|
||||
- [ ] Close branch gaps in `settings.ts`, `registeredKeys.ts`, `validation.ts`, and translator helpers
|
||||
- [ ] Považujte zbývající soubory s nízkým pokrytím za blokátory
|
||||
- [ ] Přidejte regresní testy pro každou odhalenou produkční chybu opravenou během push na 90 %
|
||||
- [ ] Zvyšte bránu pokrytí v CI pouze poté, co bude místní základní linie stabilní po dobu alespoň dvou po sobě jdoucích běhů## Ratchet policy
|
||||
|
||||
### Phase 7: 85% -> 90%
|
||||
Aktualizujte prahové hodnoty `npm run test:coverage` až poté, co projekt skutečně překročí další milník s pohodlným bufferem.
|
||||
|
||||
- [ ] Treat the remaining low-coverage files as blockers
|
||||
- [ ] Add regression tests for every uncovered production bug fixed during the push to 90%
|
||||
- [ ] Raise the coverage gate in CI only after the local baseline is stable for at least two consecutive runs
|
||||
|
||||
## Ratchet policy
|
||||
|
||||
Update `npm run test:coverage` thresholds only after the project actually exceeds the next milestone with a comfortable buffer.
|
||||
|
||||
Recommended ratchet sequence:
|
||||
Doporučené pořadí ráčny:
|
||||
|
||||
1. 55/60/55
|
||||
2. 60/62/58
|
||||
@@ -163,8 +137,6 @@ Recommended ratchet sequence:
|
||||
7. 85/80/84
|
||||
8. 90/85/88
|
||||
|
||||
Order is `statements-lines / branches / functions`.
|
||||
Pořadí je `výkazy-řádky / větve / funkce`.## Known gap
|
||||
|
||||
## Known gap
|
||||
|
||||
The current coverage command measures the main Node unit suite and includes source reached from it, including `open-sse`. It does not yet merge Vitest coverage into a single unified report. That merge is worth doing later, but it is not a blocker for starting the 60% -> 80% climb.
|
||||
Příkaz aktuálního pokrytí měří hlavní sadu jednotek uzlů a zahrnuje zdroj z ní dosažený, včetně `open-sse`. Zatím neslučuje pokrytí Vitestem do jediné jednotné zprávy. Toto sloučení stojí za to udělat později, ale není to překážka pro začátek stoupání 60% -> 80%.
|
||||
|
||||
@@ -1,145 +1,105 @@
|
||||
# OmniRoute — Dashboard Features Gallery (Čeština)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../../docs/FEATURES.md) · 🇪🇸 [es](../../es/docs/FEATURES.md) · 🇫🇷 [fr](../../fr/docs/FEATURES.md) · 🇩🇪 [de](../../de/docs/FEATURES.md) · 🇮🇹 [it](../../it/docs/FEATURES.md) · 🇷🇺 [ru](../../ru/docs/FEATURES.md) · 🇨🇳 [zh-CN](../../zh-CN/docs/FEATURES.md) · 🇯🇵 [ja](../../ja/docs/FEATURES.md) · 🇰🇷 [ko](../../ko/docs/FEATURES.md) · 🇸🇦 [ar](../../ar/docs/FEATURES.md) · 🇮🇳 [hi](../../hi/docs/FEATURES.md) · 🇮🇳 [in](../../in/docs/FEATURES.md) · 🇹🇭 [th](../../th/docs/FEATURES.md) · 🇻🇳 [vi](../../vi/docs/FEATURES.md) · 🇮🇩 [id](../../id/docs/FEATURES.md) · 🇲🇾 [ms](../../ms/docs/FEATURES.md) · 🇳🇱 [nl](../../nl/docs/FEATURES.md) · 🇵🇱 [pl](../../pl/docs/FEATURES.md) · 🇸🇪 [sv](../../sv/docs/FEATURES.md) · 🇳🇴 [no](../../no/docs/FEATURES.md) · 🇩🇰 [da](../../da/docs/FEATURES.md) · 🇫🇮 [fi](../../fi/docs/FEATURES.md) · 🇵🇹 [pt](../../pt/docs/FEATURES.md) · 🇷🇴 [ro](../../ro/docs/FEATURES.md) · 🇭🇺 [hu](../../hu/docs/FEATURES.md) · 🇧🇬 [bg](../../bg/docs/FEATURES.md) · 🇸🇰 [sk](../../sk/docs/FEATURES.md) · 🇺🇦 [uk-UA](../../uk-UA/docs/FEATURES.md) · 🇮🇱 [he](../../he/docs/FEATURES.md) · 🇵🇭 [phi](../../phi/docs/FEATURES.md) · 🇧🇷 [pt-BR](../../pt-BR/docs/FEATURES.md) · 🇨🇿 [cs](../../cs/docs/FEATURES.md) · 🇹🇷 [tr](../../tr/docs/FEATURES.md)
|
||||
|
||||
---
|
||||
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
---
|
||||
Vizuální průvodce každou částí řídicího panelu OmniRoute.---
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (Qoder, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

|
||||
Správa připojení poskytovatelů AI: poskytovatelé OAuth (Claude Code, Codex, Gemini CLI), poskytovatelé klíčů API (Groq, DeepSeek, OpenRouter) a bezplatní poskytovatelé (Qoder, Qwen, Kiro). Účty Kiro zahrnují sledování zůstatku kreditu – zbývající kredity, celkový příspěvek a datum obnovení jsou viditelné v Dashboard → Použití.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Combos
|
||||
|
||||
Create model routing combos with 6 strategies: priority, weighted, round-robin, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback and includes quick templates and readiness checks.
|
||||
|
||||

|
||||
Vytvářejte komba směrování modelů se 6 strategiemi: prioritní, vážená, cyklická, náhodná, nejméně používaná a nákladově optimalizovaná. Každé kombo řetězí více modelů s automatickým nouzovým návratem a zahrnuje rychlé šablony a kontroly připravenosti.
|
||||
|
||||
---
|
||||
|
||||
## 📊 Analytics
|
||||
|
||||
Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
|
||||
|
||||

|
||||
Komplexní analýzy využití se spotřebou tokenů, odhady nákladů, teplotní mapy aktivit, týdenní distribuční grafy a rozpisy podle poskytovatelů.
|
||||
|
||||
---
|
||||
|
||||
## 🏥 System Health
|
||||
|
||||
Real-time monitoring: uptime, memory, version, latency percentiles (p50/p95/p99), cache statistics, and provider circuit breaker states.
|
||||
|
||||

|
||||
Monitorování v reálném čase: doba provozuschopnosti, paměť, verze, percentily latence (p50/p95/p99), statistika mezipaměti a stavy jističe poskytovatele.
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Translator Playground
|
||||
|
||||
Four modes for debugging API translations: **Playground** (format converter), **Chat Tester** (live requests), **Test Bench** (batch tests), and **Live Monitor** (real-time stream).
|
||||
|
||||

|
||||
Čtyři režimy pro ladění překladů API:**Playground**(konvertor formátů),**Chat Tester**(živé požadavky),**Test Bench**(dávkové testy) a**Live Monitor**(stream v reálném čase).
|
||||
|
||||
---
|
||||
|
||||
## 🎮 Model Playground _(v2.0.9+)_
|
||||
|
||||
Test any model directly from the dashboard. Select provider, model, and endpoint, write prompts with Monaco Editor, stream responses in real-time, abort mid-stream, and view timing metrics.
|
||||
|
||||
---
|
||||
Otestujte jakýkoli model přímo z palubní desky. Vyberte poskytovatele, model a koncový bod, pište výzvy pomocí editoru Monaco, streamujte odpovědi v reálném čase, rušte uprostřed streamu a zobrazujte metriky časování.---
|
||||
|
||||
## 🎨 Themes _(v2.0.5+)_
|
||||
|
||||
Customizable color themes for the entire dashboard. Choose from 7 preset colors (Coral, Blue, Red, Green, Violet, Orange, Cyan) or create a custom theme by picking any hex color. Supports light, dark, and system mode.
|
||||
|
||||
---
|
||||
Přizpůsobitelné barevné motivy pro celý přístrojový panel. Vyberte si ze 7 přednastavených barev (korálová, modrá, červená, zelená, fialová, oranžová, azurová) nebo si vytvořte vlastní motiv výběrem libovolné šestihranné barvy. Podporuje světlý, tmavý a systémový režim.---
|
||||
|
||||
## ⚙️ Settings
|
||||
|
||||
Comprehensive settings panel with tabs:
|
||||
Komplexní panel nastavení s kartami:
|
||||
|
||||
- **General** — System storage, backup management (export/import database)
|
||||
- **Appearance** — Theme selector (dark/light/system), color theme presets and custom colors, health log visibility, sidebar item visibility controls
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning, auto-disable banned accounts, provider expiration monitoring
|
||||
- **Advanced** — Configuration overrides, configuration audit trail, fallback degradation mode
|
||||
|
||||

|
||||
-**Obecné**— Systémové úložiště, správa zálohování (export/import databáze) -**Vzhled**— Volič motivu (tmavý/světlý/systém), přednastavení barevných motivů a vlastní barvy, viditelnost zdravotního deníku, ovládací prvky viditelnosti položek na postranním panelu -**Zabezpečení**— Ochrana koncových bodů API, blokování vlastního poskytovatele, filtrování IP, informace o relaci -**Směrování**— Modelové aliasy, degradace úloh na pozadí -**Odolnost**- Perzistence rychlostního limitu, ladění jističe, automatické deaktivace zakázaných účtů, sledování expirace poskytovatele -**Advanced**– Přepisy konfigurace, auditní záznam konfigurace, režim degradace záložního řešení
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI Tools
|
||||
|
||||
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor, and Factory Droid. Features automated config apply/reset, connection profiles, and model mapping.
|
||||
|
||||

|
||||
Konfigurace jedním kliknutím pro nástroje pro kódování AI: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor a Factory Droid. Obsahuje automatické nastavení konfigurace/resetování, profily připojení a mapování modelu.
|
||||
|
||||
---
|
||||
|
||||
## 🤖 CLI Agents _(v2.0.11+)_
|
||||
|
||||
Dashboard for discovering and managing CLI agents. Shows a grid of 14 built-in agents (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) with:
|
||||
Dashboard pro zjišťování a správu agentů CLI. Zobrazuje mřížku 14 vestavěných agentů (Codex, Claude, Goose, Gemini CLI, OpenClaw, Aider, OpenCode, Cline, Qwen Code, ForgeCode, Amazon Q, Open Interpreter, Cursor CLI, Warp) s:
|
||||
|
||||
- **Installation status** — Installed / Not Found with version detection
|
||||
- **Protocol badges** — stdio, HTTP, etc.
|
||||
- **Custom agents** — Register any CLI tool via form (name, binary, version command, spawn args)
|
||||
- **CLI Fingerprint Matching** — Per-provider toggle to match native CLI request signatures, reducing ban risk while preserving proxy IP
|
||||
|
||||
---
|
||||
-**Stav instalace**— Instalováno / Nenalezeno s detekcí verze -**Odznaky protokolu**— stdio, HTTP atd. -**Vlastní agenti**— Zaregistrujte jakýkoli nástroj CLI prostřednictvím formuláře (název, binární soubor, příkaz verze, spawn args) -**CLI Fingerprint Matching**– Přepínání na jednotlivé poskytovatele, aby odpovídalo nativním podpisům požadavků CLI, čímž se snižuje riziko zákazu při zachování IP adresy proxy---
|
||||
|
||||
## 🖼️ Media _(v2.0.3+)_
|
||||
|
||||
Generate images, videos, and music from the dashboard. Supports OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open, and MusicGen.
|
||||
|
||||
---
|
||||
Generujte obrázky, videa a hudbu z řídicího panelu. Podporuje OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open a MusicGen.---
|
||||
|
||||
## 📝 Request Logs
|
||||
|
||||
Real-time request logging with filtering by provider, model, account, and API key. Shows status codes, token usage, latency, and response details.
|
||||
|
||||

|
||||
Protokolování požadavků v reálném čase s filtrováním podle poskytovatele, modelu, účtu a klíče API. Zobrazuje stavové kódy, využití tokenu, latenci a podrobnosti o odpovědi.
|
||||
|
||||
---
|
||||
|
||||
## 🌐 API Endpoint
|
||||
|
||||
Your unified API endpoint with capability breakdown: Chat Completions, Responses API, Embeddings, Image Generation, Reranking, Audio Transcription, Text-to-Speech, Moderations, and registered API keys. Cloudflare Quick Tunnel integration and cloud proxy support for remote access.
|
||||
|
||||

|
||||
Váš sjednocený koncový bod API s rozdělením schopností: Dokončení chatu, API odpovědí, vkládání, generování obrázků, změna pořadí, přepis zvuku, převod textu na řeč, moderování a registrované klíče rozhraní API. Integrace Cloudflare Quick Tunnel a podpora cloudového proxy pro vzdálený přístup.
|
||||
|
||||
---
|
||||
|
||||
## 🔑 API Key Management
|
||||
|
||||
Create, scope, and revoke API keys. Each key can be restricted to specific models/providers with full access or read-only permissions. Visual key management with usage tracking.
|
||||
|
||||
---
|
||||
Vytvářejte, upravujte a rušte klíče API. Každý klíč může být omezen na konkrétní modely/poskytovatele s plným přístupem nebo oprávněním pouze pro čtení. Vizuální správa klíčů se sledováním využití.---
|
||||
|
||||
## 📋 Audit Log
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
|
||||
---
|
||||
Sledování administrativních akcí s filtrováním podle typu akce, aktéra, cíle, IP adresy a časového razítka. Úplná historie událostí zabezpečení.---
|
||||
|
||||
## 🖥️ Desktop Application
|
||||
|
||||
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, auto-update, and one-click install.
|
||||
Nativní desktopová aplikace Electron pro Windows, macOS a Linux. Spusťte OmniRoute jako samostatnou aplikaci s integrací na systémové liště, offline podporou, automatickou aktualizací a instalací jedním kliknutím.
|
||||
|
||||
Key features:
|
||||
Klíčové vlastnosti:
|
||||
|
||||
- Server readiness polling (no blank screen on cold start)
|
||||
- System tray with port management
|
||||
- Content Security Policy
|
||||
- Single-instance lock
|
||||
- Auto-update on restart
|
||||
- Platform-conditional UI (macOS traffic lights, Windows/Linux default titlebar)
|
||||
- Hardened Electron build packaging — symlinked `node_modules` in the standalone bundle is detected and rejected before packaging, preventing runtime dependency on the build machine (v2.5.5+)
|
||||
- Dotazování připravenosti serveru (žádná prázdná obrazovka při studeném startu)
|
||||
- Systémová lišta se správou portů
|
||||
- Zásady zabezpečení obsahu
|
||||
- Jednoinstanční zámek
|
||||
- Automatická aktualizace při restartu
|
||||
- Platformově podmíněné uživatelské rozhraní (semafory macOS, výchozí titulek Windows/Linux)
|
||||
- Balení sestavení Hardened Electron – symbolicky propojené `node_modules` v samostatném balíčku jsou detekovány a odmítnuty před zabalením, čímž se zabrání závislosti běhu na sestavení (v2.5.5+)
|
||||
|
||||
📖 See [`electron/README.md`](../electron/README.md) for full documentation.
|
||||
📖 Úplnou dokumentaci naleznete v [`electron/README.md`](../electron/README.md).
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user