mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-27 02:12:19 +03:00
Compare commits
499 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d6f6520a79 | ||
|
|
cc2bb4d719 | ||
|
|
3859f1c9ae | ||
|
|
5f8d774e19 | ||
|
|
538a3e855c | ||
|
|
03f2ef1e2b | ||
|
|
237d0746cf | ||
|
|
33b6c58087 | ||
|
|
e96b023d04 | ||
|
|
7ac1d4621b | ||
|
|
a2d7cbe8fe | ||
|
|
c74ed29739 | ||
|
|
6c8501f122 | ||
|
|
941e945f74 | ||
|
|
f2844d59e4 | ||
|
|
047ff187f6 | ||
|
|
1136c40811 | ||
|
|
5a78dc864f | ||
|
|
15c98c3048 | ||
|
|
0a5b005ce5 | ||
|
|
4d64e64127 | ||
|
|
5470c70cd0 | ||
|
|
47959ee395 | ||
|
|
7c34c178cd | ||
|
|
ac7cb41483 | ||
|
|
0ab388b88e | ||
|
|
54448902f1 | ||
|
|
12107a02fd | ||
|
|
eace06efdc | ||
|
|
ee0afa1eec | ||
|
|
83cdd0dafe | ||
|
|
5be025f1d1 | ||
|
|
c651842ea1 | ||
|
|
423abe6788 | ||
|
|
4003c38fd1 | ||
|
|
3e0c322fd4 | ||
|
|
7fcdd4abdd | ||
|
|
3f3280b2d4 | ||
|
|
aae2399631 | ||
|
|
03bd2b6803 | ||
|
|
48754fd999 | ||
|
|
c496ebdef9 | ||
|
|
c009c40606 | ||
|
|
b29456c8e5 | ||
|
|
38266bf2ff | ||
|
|
c2e51f8948 | ||
|
|
c54a57838e | ||
|
|
64f040bddd | ||
|
|
1a099ea2f2 | ||
|
|
13c45807ef | ||
|
|
dfbb9d5fff | ||
|
|
a7fe369ea0 | ||
|
|
b62e6c5a69 | ||
|
|
92e29a6ad7 | ||
|
|
eeb9c69aa3 | ||
|
|
b7662ed5a1 | ||
|
|
9d6296f610 | ||
|
|
fd2a1320e0 | ||
|
|
8a8a6a4a82 | ||
|
|
8cdc14eec1 | ||
|
|
a1200b2fb5 | ||
|
|
c88c29eddc | ||
|
|
2845c4de98 | ||
|
|
bfa9cd15b7 | ||
|
|
659e2b414d | ||
|
|
7bcb58e3db | ||
|
|
2d7d7776a6 | ||
|
|
c5f429521c | ||
|
|
426d8636bc | ||
|
|
a265c7096e | ||
|
|
1c9953b1ba | ||
|
|
601cc21a44 | ||
|
|
102c42dfe4 | ||
|
|
4953727aa7 | ||
|
|
e6af874b47 | ||
|
|
801b4eef4c | ||
|
|
fe5c20a04e | ||
|
|
246fd05fae | ||
|
|
a09b298127 | ||
|
|
f89f40778f | ||
|
|
3d0c8d8d45 | ||
|
|
0e5e8bf14e | ||
|
|
ce34d329d3 | ||
|
|
eaf4a5805c | ||
|
|
8420e565d4 | ||
|
|
00df10c29a | ||
|
|
1b68deb0f6 | ||
|
|
d1497c9ac8 | ||
|
|
03d4cbf6d5 | ||
|
|
718be831af | ||
|
|
9d5ec523be | ||
|
|
81c43b45fb | ||
|
|
146a491769 | ||
|
|
4c53388579 | ||
|
|
3403ddcc6e | ||
|
|
684b81d835 | ||
|
|
4f32da57fd | ||
|
|
97265e48b3 | ||
|
|
64797158e2 | ||
|
|
8359293dcd | ||
|
|
b2dc53d18b | ||
|
|
edf8dd2a12 | ||
|
|
5a777bd598 | ||
|
|
bd39e01ee1 | ||
|
|
e3ed29aab6 | ||
|
|
896ce9c0e2 | ||
|
|
82934132e9 | ||
|
|
a2012b70de | ||
|
|
bcfeba8a57 | ||
|
|
d3dfd9ce57 | ||
|
|
aa06d5d356 | ||
|
|
448c8a29e1 | ||
|
|
928b7120f4 | ||
|
|
a3deacd718 | ||
|
|
78959fffbd | ||
|
|
1788616e52 | ||
|
|
c61e6d0777 | ||
|
|
41d91d628a | ||
|
|
a3bc7620b1 | ||
|
|
8064c588dc | ||
|
|
564e983c68 | ||
|
|
e1da181740 | ||
|
|
c63209200e | ||
|
|
737808cf53 | ||
|
|
a197bb7736 | ||
|
|
f9dd967bc5 | ||
|
|
44e4d55a66 | ||
|
|
095c84ac16 | ||
|
|
e063eae727 | ||
|
|
f02c5b5c69 | ||
|
|
838f1d645c | ||
|
|
ce2c30c437 | ||
|
|
d56fae0a7b | ||
|
|
e45ef00bef | ||
|
|
e9f31f7394 | ||
|
|
7c10a98eb2 | ||
|
|
f260483101 | ||
|
|
389e6e5c9e | ||
|
|
1cfd5866be | ||
|
|
c7ceac7f41 | ||
|
|
cd6eca0424 | ||
|
|
8c6136fea0 | ||
|
|
9644444028 | ||
|
|
9c4154291d | ||
|
|
533f5f6da6 | ||
|
|
1b8de756cd | ||
|
|
650b415537 | ||
|
|
04b50329fc | ||
|
|
25aab8c55c | ||
|
|
ceda2e70c1 | ||
|
|
2908303d4b | ||
|
|
a9f69711c6 | ||
|
|
a8ab16a720 | ||
|
|
8091b6b508 | ||
|
|
a00ef0fc7e | ||
|
|
5ce6d615a4 | ||
|
|
e06b69cdac | ||
|
|
d261ae7883 | ||
|
|
6fa77a63d7 | ||
|
|
f76c1b32d6 | ||
|
|
0aede2ef63 | ||
|
|
1e3a2e0a27 | ||
|
|
1bdabf43db | ||
|
|
05e568feb0 | ||
|
|
81e2519436 | ||
|
|
ef623c9bb5 | ||
|
|
da581525a6 | ||
|
|
6ff7b6570c | ||
|
|
8b2081837e | ||
|
|
ce978b602a | ||
|
|
9b00f5d550 | ||
|
|
d98ec59c79 | ||
|
|
d79b55be5a | ||
|
|
1f9a402dcd | ||
|
|
f9bcc9418b | ||
|
|
08256a3502 | ||
|
|
9b255e643a | ||
|
|
ca1f918e9e | ||
|
|
bb3fe1cd48 | ||
|
|
5d7772ecb0 | ||
|
|
56ce618eca | ||
|
|
605c3f9be1 | ||
|
|
b0381c7542 | ||
|
|
2f0894c220 | ||
|
|
b328ed5fa9 | ||
|
|
7d72f1711f | ||
|
|
d139b4557f | ||
|
|
cd05e03d63 | ||
|
|
e25029939d | ||
|
|
53de27417d | ||
|
|
74d3374d5c | ||
|
|
3ae00bebe4 | ||
|
|
f9df72c4d7 | ||
|
|
d0fb4576a8 | ||
|
|
0e4b0b3540 | ||
|
|
df1105d0c6 | ||
|
|
44478c36a3 | ||
|
|
fa267274b0 | ||
|
|
0db272946a | ||
|
|
91015b6499 | ||
|
|
2979a36a7c | ||
|
|
72f6d6b7b9 | ||
|
|
d81a7bcedf | ||
|
|
8fbbe8b82b | ||
|
|
271f5f9c64 | ||
|
|
7c992ffd21 | ||
|
|
fc2af8ba87 | ||
|
|
c8a539a6cb | ||
|
|
b7cdaa662a | ||
|
|
0a25930020 | ||
|
|
8643f4015f | ||
|
|
1854711aff | ||
|
|
c905119d82 | ||
|
|
c581ca8339 | ||
|
|
ccf9d9214a | ||
|
|
d37c8b732f | ||
|
|
f707fc1cad | ||
|
|
b1c713de60 | ||
|
|
0f13965391 | ||
|
|
8642e2b721 | ||
|
|
441534853b | ||
|
|
82f42c8664 | ||
|
|
5cd318fa9a | ||
|
|
5506071e9a | ||
|
|
ced98f2da7 | ||
|
|
282ec65e8b | ||
|
|
8e06dc5ace | ||
|
|
bfd3e2c01b | ||
|
|
a1957f0923 | ||
|
|
11a02ba361 | ||
|
|
4643c19abc | ||
|
|
a3369df62f | ||
|
|
4297c42597 | ||
|
|
e06e7157ac | ||
|
|
22f9e6f4c0 | ||
|
|
4b7a9233e7 | ||
|
|
204839f702 | ||
|
|
d15e3109ee | ||
|
|
8b513ee8f8 | ||
|
|
2c1488e65a | ||
|
|
8ebe1cc2d8 | ||
|
|
b0d6c15e63 | ||
|
|
3a3c7a7968 | ||
|
|
783d7ae605 | ||
|
|
bbf7a6b2f8 | ||
|
|
0fe6e24554 | ||
|
|
4bbaf55586 | ||
|
|
cda765a02d | ||
|
|
36856b18db | ||
|
|
66f0a8f994 | ||
|
|
455231170f | ||
|
|
5faeb58ab0 | ||
|
|
056e4a88ff | ||
|
|
8fd944ccf7 | ||
|
|
86105a547c | ||
|
|
9806648c07 | ||
|
|
6186babdb3 | ||
|
|
f2ecefb54a | ||
|
|
43bd529b78 | ||
|
|
9c82b3d4ca | ||
|
|
b19e6a8e87 | ||
|
|
e3a2bd75f3 | ||
|
|
da39e1485f | ||
|
|
88cc53a4b0 | ||
|
|
245243c7e7 | ||
|
|
759ac0df3d | ||
|
|
db8d97b6de | ||
|
|
27d66e4b3e | ||
|
|
ca7854210d | ||
|
|
c009c993c3 | ||
|
|
00188f75ae | ||
|
|
4d086542aa | ||
|
|
1555883633 | ||
|
|
8f2c0acc7e | ||
|
|
0e30d15c01 | ||
|
|
da14390fe0 | ||
|
|
11c0cff4ef | ||
|
|
e322376996 | ||
|
|
4fbe45f30a | ||
|
|
2cd0f60c3c | ||
|
|
1b354be827 | ||
|
|
7db280ee64 | ||
|
|
192c06cadf | ||
|
|
ad7e7abda0 | ||
|
|
02ccb35e80 | ||
|
|
a8a29e17c5 | ||
|
|
75a6d850fc | ||
|
|
b0f5f92f1a | ||
|
|
eaddb6f0fa | ||
|
|
5cff98ea75 | ||
|
|
76127415a4 | ||
|
|
56936fe0e3 | ||
|
|
dfbbbeb1b4 | ||
|
|
7f3ffd935e | ||
|
|
29cf462d8f | ||
|
|
5e1693e1f7 | ||
|
|
45424ca226 | ||
|
|
d976abb5e0 | ||
|
|
92d302aed3 | ||
|
|
1e93ee5c34 | ||
|
|
1b6c502c7f | ||
|
|
4e4532c057 | ||
|
|
1e57ae5923 | ||
|
|
9055fc2129 | ||
|
|
b8fec94b0d | ||
|
|
2b6c88cd26 | ||
|
|
f6c0744d67 | ||
|
|
639b49fc5b | ||
|
|
c0252f7b13 | ||
|
|
a87d64372f | ||
|
|
02b19e63e8 | ||
|
|
dba16363b7 | ||
|
|
d20a2b3e44 | ||
|
|
677f5f8713 | ||
|
|
7da23a90d4 | ||
|
|
8dad2d32b6 | ||
|
|
d07a5f0df7 | ||
|
|
55a9e31932 | ||
|
|
e62be7e6b3 | ||
|
|
7f9ec724ae | ||
|
|
daaa3a8782 | ||
|
|
d1c62420bf | ||
|
|
1c10cfe4bc | ||
|
|
a4252d52ce | ||
|
|
1d7bc5fed7 | ||
|
|
763fdf3135 | ||
|
|
82314562e7 | ||
|
|
69e9bd81e9 | ||
|
|
26f927f798 | ||
|
|
2042dcf991 | ||
|
|
87ffe41d8c | ||
|
|
943a9374b4 | ||
|
|
8956ffef73 | ||
|
|
4383e7d807 | ||
|
|
863055768e | ||
|
|
2c1da9e146 | ||
|
|
845787ab7f | ||
|
|
1db948e9bb | ||
|
|
f0d00bcee5 | ||
|
|
1e9a9adbad | ||
|
|
d87c7c3b8c | ||
|
|
eb3c834609 | ||
|
|
e53c76081f | ||
|
|
134316328c | ||
|
|
4767561f02 | ||
|
|
2d6b31b606 | ||
|
|
a22f0a4e7b | ||
|
|
5a244aa12a | ||
|
|
69d28bec4d | ||
|
|
c859665c6b | ||
|
|
e7b19758f3 | ||
|
|
623c63baf6 | ||
|
|
a3ad7c6c2e | ||
|
|
afc9362ca5 | ||
|
|
f6b125e8c2 | ||
|
|
5df3c22be8 | ||
|
|
11a0df5443 | ||
|
|
e27a2a0d55 | ||
|
|
dc8abe60ee | ||
|
|
afe2ab37e4 | ||
|
|
f7bd99f965 | ||
|
|
f5238944b4 | ||
|
|
c7ae9c30c2 | ||
|
|
82f7a12a46 | ||
|
|
f494a8531b | ||
|
|
36ed0499db | ||
|
|
46cff2200d | ||
|
|
5ea6ad4a9e | ||
|
|
6cad4fae8e | ||
|
|
8df24c855b | ||
|
|
f25882c0e9 | ||
|
|
be6c769192 | ||
|
|
a4276444b5 | ||
|
|
0af27b8d8a | ||
|
|
542eb0e719 | ||
|
|
c658b39270 | ||
|
|
52ef3dfc7e | ||
|
|
57da407693 | ||
|
|
d2d6fc5883 | ||
|
|
6a7a6022d4 | ||
|
|
b53eafa615 | ||
|
|
c949214e99 | ||
|
|
887cf25b65 | ||
|
|
dd6142196f | ||
|
|
902c7244d1 | ||
|
|
4f11762c68 | ||
|
|
8a7f7c1ba0 | ||
|
|
af46f87eed | ||
|
|
fd749d1e0b | ||
|
|
5046f90dfa | ||
|
|
cf13e95610 | ||
|
|
5763609008 | ||
|
|
6d672ab09a | ||
|
|
ac68022233 | ||
|
|
c2b31f6b20 | ||
|
|
54b1d8c8de | ||
|
|
cd1ab696b2 | ||
|
|
d9d0640f6e | ||
|
|
e19046116a | ||
|
|
82a621ec08 | ||
|
|
ce560ebe9d | ||
|
|
f900a81ec9 | ||
|
|
2a620b178d | ||
|
|
5aaaad529b | ||
|
|
4e15ca6bbd | ||
|
|
8555a3a106 | ||
|
|
3a39ae6231 | ||
|
|
00e6b7cf2c | ||
|
|
ebd1e5421b | ||
|
|
2feb2df30d | ||
|
|
ba38dc738b | ||
|
|
9233edb6cd | ||
|
|
f697c56922 | ||
|
|
5ab6a3b431 | ||
|
|
25cd0b3612 | ||
|
|
6e1bf4652d | ||
|
|
3991c96c78 | ||
|
|
70008e67e4 | ||
|
|
0d1e6685f6 | ||
|
|
60d1d13c6a | ||
|
|
ade1e5f345 | ||
|
|
0a59ef4996 | ||
|
|
ace3e47d22 | ||
|
|
9865401636 | ||
|
|
1343768de1 | ||
|
|
743cfcbb3c | ||
|
|
44ee62e391 | ||
|
|
47445ebf5c | ||
|
|
6b0638da30 | ||
|
|
74a0585683 | ||
|
|
9aaebbcd2a | ||
|
|
2348680a2b | ||
|
|
59a8b8db35 | ||
|
|
2ba46a622b | ||
|
|
9013236718 | ||
|
|
eab96cc94b | ||
|
|
7f66e82f16 | ||
|
|
c74054d928 | ||
|
|
5428c9b9a8 | ||
|
|
db0bda2810 | ||
|
|
c4efad3ea7 | ||
|
|
62995b640d | ||
|
|
9a476d310a | ||
|
|
bc09eb64a6 | ||
|
|
8e4873d53e | ||
|
|
5874bd3de6 | ||
|
|
a1dc2270a2 | ||
|
|
1c2f553a7c | ||
|
|
049ddff6fe | ||
|
|
9429d1639e | ||
|
|
af7ca4baf7 | ||
|
|
7906fdfc1d | ||
|
|
9911272898 | ||
|
|
8909ae041e | ||
|
|
c9a15772b0 | ||
|
|
91f3bd4056 | ||
|
|
2306081dab | ||
|
|
8963c62adb | ||
|
|
e4a11bd6d0 | ||
|
|
2f6e63771f | ||
|
|
cbd60c853e | ||
|
|
2d8091340f | ||
|
|
2025c16c82 | ||
|
|
811fb7f9b2 | ||
|
|
a2bd32e76c | ||
|
|
89c07f4e8a | ||
|
|
ac89069671 | ||
|
|
7cb420d8e6 | ||
|
|
d3919d441f | ||
|
|
4b5824babc | ||
|
|
fb87df14fd | ||
|
|
da9e4e929b | ||
|
|
10b23b15ae | ||
|
|
30fba39b35 | ||
|
|
5a75ff67c9 | ||
|
|
358828b617 | ||
|
|
e080c4a16a | ||
|
|
04b7e38baf | ||
|
|
7ee23fbe19 | ||
|
|
c49bdb4ebb | ||
|
|
0f7efed8d5 | ||
|
|
d07bc6dcf3 | ||
|
|
d607d46fa3 | ||
|
|
2225dd14aa | ||
|
|
f6c0e7bbbe | ||
|
|
c4675c5219 | ||
|
|
2d977a3c4d | ||
|
|
9405918258 | ||
|
|
a69d7dd4b5 | ||
|
|
428e6cb53f | ||
|
|
c9a2955d28 | ||
|
|
7aefcd3437 | ||
|
|
79f4f79c46 | ||
|
|
c11c275678 | ||
|
|
bbcd1d3a08 | ||
|
|
3342d5b931 | ||
|
|
f96ee44213 | ||
|
|
bc53fe0cd9 | ||
|
|
97a67b5d3e |
@@ -4,52 +4,99 @@ description: Deploy the latest OmniRoute code to the Akamai VPS (69.164.221.35)
|
||||
|
||||
# Deploy to VPS Workflow
|
||||
|
||||
Deploy OmniRoute to the production VPS using Node.js + PM2 (no Docker).
|
||||
Deploy OmniRoute to the production VPS using `npm pack + scp` + PM2.
|
||||
|
||||
**VPS:** `69.164.221.35` (Akamai, Ubuntu 24.04, 1GB RAM + 2.5GB swap)
|
||||
**App path:** `/opt/omniroute-app`
|
||||
**Local VPS:** `192.168.0.15` (same setup)
|
||||
**Process manager:** PM2 (`omniroute`)
|
||||
**Port:** `20128`
|
||||
**PM2 entry:** `/usr/lib/node_modules/omniroute/app/server.js`
|
||||
|
||||
> [!IMPORTANT]
|
||||
> PM2 runs from the global npm package at `/usr/lib/node_modules/omniroute`.
|
||||
> The Next.js standalone build is at `app/server.js` inside that directory.
|
||||
> The npm registry rejects packages > 100MB, so deployment uses **npm pack + scp**.
|
||||
|
||||
> [!CAUTION]
|
||||
> **NEVER** use `pm2 restart omniroute` after `npm install -g`. This drops env vars.
|
||||
> Always use `pm2 delete omniroute && pm2 start <ecosystem.config.cjs> --update-env`.
|
||||
> After `npm install -g`, always rebuild better-sqlite3: `cd .../app && npm rebuild better-sqlite3`
|
||||
|
||||
## Steps
|
||||
|
||||
### 1. Push to GitHub
|
||||
### 1. Build + pack locally
|
||||
|
||||
Ensure all changes are committed and pushed:
|
||||
Run the full build (includes hash-strip patch) and create the .tgz:
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && npm pack --ignore-scripts
|
||||
```
|
||||
|
||||
### 2. SSH into VPS, pull latest code, rebuild, and restart
|
||||
### 2. Copy to both VPS and install
|
||||
|
||||
// turbo-all
|
||||
|
||||
```bash
|
||||
ssh root@69.164.221.35 "
|
||||
cd /opt/omniroute-app &&
|
||||
git fetch origin &&
|
||||
git reset --hard origin/main &&
|
||||
export NODE_OPTIONS='--max-old-space-size=1536' &&
|
||||
npm install --no-audit --no-fund &&
|
||||
npm run build &&
|
||||
pm2 restart omniroute &&
|
||||
pm2 save &&
|
||||
echo '✅ Deploy complete!'
|
||||
"
|
||||
scp omniroute-*.tgz root@69.164.221.35:/tmp/ && scp omniroute-*.tgz root@192.168.0.15:/tmp/
|
||||
```
|
||||
|
||||
```bash
|
||||
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'"
|
||||
```
|
||||
|
||||
```bash
|
||||
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'"
|
||||
```
|
||||
|
||||
### 3. Verify the deployment
|
||||
|
||||
```bash
|
||||
ssh root@69.164.221.35 "pm2 list && curl -s -o /dev/null -w 'HTTP %{http_code}' http://localhost:20128/"
|
||||
ssh root@69.164.221.35 "pm2 list && cat \$(npm root -g)/omniroute/app/package.json | grep version | head -1 && curl -s -o /dev/null -w 'HTTP %{http_code}' http://localhost:20128/"
|
||||
```
|
||||
|
||||
Expected: PM2 shows `online`, HTTP returns `307` (redirect to login).
|
||||
```bash
|
||||
ssh root@192.168.0.15 "pm2 list && cat \$(npm root -g)/omniroute/app/package.json | grep version | head -1 && curl -s -X POST http://localhost:20128/api/auth/login -H 'Content-Type: application/json' -d '{\"password\":\"123456\"}'"
|
||||
```
|
||||
|
||||
Expected: PM2 shows `online`, version matches, login returns `{"success":true}`.
|
||||
|
||||
## How it works
|
||||
|
||||
1. `npm run build:cli` builds Next.js standalone → `app/` and strips Turbopack hashed require() calls from chunks
|
||||
2. `npm pack --ignore-scripts` packages without re-running the build
|
||||
3. `scp` transfers the .tgz to each VPS (~286MB)
|
||||
4. `npm install -g /tmp/omniroute-*.tgz --ignore-scripts` installs pre-built package
|
||||
5. `npm rebuild better-sqlite3` recompiles native bindings for the VPS Node.js version
|
||||
6. `pm2 delete` + `pm2 start ecosystem.config.cjs --update-env` restarts with env vars
|
||||
7. `pm2 save` persists the process list for reboot survival
|
||||
|
||||
## Ecosystem Config
|
||||
|
||||
Both VPSs have `ecosystem.config.cjs` at `/root/.omniroute/ecosystem.config.cjs`.
|
||||
This file defines env vars (PORT, DATA_DIR, INITIAL_PASSWORD, OAuth secrets, etc.)
|
||||
that `pm2 restart` does NOT inject — only `pm2 start --update-env` does.
|
||||
|
||||
## PM2 Setup (one-time — if reconfiguring from scratch)
|
||||
|
||||
```bash
|
||||
ssh root@<VPS> "
|
||||
pm2 delete omniroute 2>/dev/null;
|
||||
cd /usr/lib/node_modules/omniroute/app && npm rebuild better-sqlite3 &&
|
||||
pm2 start /root/.omniroute/ecosystem.config.cjs --update-env &&
|
||||
pm2 save && pm2 startup
|
||||
"
|
||||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Ensure `/root/.omniroute/ecosystem.config.cjs` exists with all required env vars.
|
||||
> For fresh installs, copy from the existing VPS or create from the template in `.env`.
|
||||
|
||||
## Notes
|
||||
|
||||
- The VPS has only 1GB RAM. `NODE_OPTIONS='--max-old-space-size=1536'` uses swap for the build.
|
||||
- PM2 is configured with `pm2 startup` to auto-restart on reboot.
|
||||
- The `.env` file is at `/opt/omniroute-app/.env` (copied from the old Docker setup at `/opt/omniroute/.env`).
|
||||
- Nginx proxies `omniroute.online` → `localhost:20128`.
|
||||
- Env vars are in `/root/.omniroute/ecosystem.config.cjs` (NOT `.env` in app dir)
|
||||
- PM2 is configured with `pm2 startup` to auto-restart on reboot
|
||||
- Nginx proxies `omniroute.online` → `localhost:20128`
|
||||
- The VPS has only 1GB RAM — builds happen locally, never on the VPS
|
||||
- After `npm install -g`, `better-sqlite3` MUST be rebuilt in the `app/` subdir
|
||||
|
||||
@@ -4,75 +4,253 @@ description: Create a new release, bump version up to 1.x.10 threshold, update c
|
||||
|
||||
# Generate Release Workflow
|
||||
|
||||
Bump version, finalize CHANGELOG, commit, tag, push, publish to npm, and create GitHub release.
|
||||
Bump version, finalize CHANGELOG, commit, open a **PR to main** and wait for user confirmation before tagging, publishing, and deploying.
|
||||
|
||||
## Steps
|
||||
> **VERSION RULE: Always use PATCH bumps (2.x.y → 2.x.y+1)**
|
||||
> NEVER use `npm version minor` or `npm version major`.
|
||||
> Always use: `npm version patch --no-git-tag-version`
|
||||
> The threshold rule: when `y` reaches 10, bump to `2.(x+1).0` — e.g. `2.1.10` → `2.2.0`.
|
||||
|
||||
### 1. Determine new version
|
||||
---
|
||||
|
||||
Check current version in `package.json` and increment the patch number:
|
||||
## ⚠️ Two-Phase Flow
|
||||
|
||||
```
|
||||
Phase 1 (automated): bump → docs → i18n → commit → push → open PR
|
||||
↕ 🛑 STOP: Notify user, wait for PR confirmation
|
||||
Phase 2 (post-merge): tag → publish → GitHub release → Docker → deploy
|
||||
```
|
||||
|
||||
**NEVER push directly to main or create tags before the user confirms the PR.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 1: Pre-Merge
|
||||
|
||||
### 1. Create release branch
|
||||
|
||||
```bash
|
||||
git checkout -b release/v2.x.y
|
||||
```
|
||||
|
||||
### 2. Determine new version
|
||||
|
||||
Check current version in `package.json` and increment the **patch** number only:
|
||||
|
||||
```bash
|
||||
grep '"version"' package.json
|
||||
```
|
||||
|
||||
Version format: `1.x.y` — increment `y` for patch, `x` for minor (threshold: y=10 triggers x+1).
|
||||
Version format: `2.x.y` — examples:
|
||||
|
||||
### 2. Finalize CHANGELOG.md
|
||||
- `2.1.2` → `2.1.3` (patch)
|
||||
- `2.1.9` → `2.1.10` (patch)
|
||||
- `2.1.10` → `2.2.0` (minor threshold — do manually with `sed`)
|
||||
|
||||
Replace `[Unreleased]` header with the new version and date:
|
||||
> **⚠️ ATOMIC COMMIT RULE — Version bump MUST happen before committing feature files.**
|
||||
>
|
||||
> **CORRECT order:**
|
||||
>
|
||||
> 1. `npm version patch --no-git-tag-version` ← bump first
|
||||
> 2. implement features / fix bugs
|
||||
> 3. `git add -A && git commit -m "chore(release): v2.x.y — all changes in ONE commit"`
|
||||
>
|
||||
> **OR if features are already staged:**
|
||||
>
|
||||
> 1. implement features (do NOT commit yet)
|
||||
> 2. `npm version patch --no-git-tag-version` ← bump before committing
|
||||
> 3. `git add -A && git commit -m "chore(release): v2.x.y — all changes in ONE commit"`
|
||||
>
|
||||
> **NEVER do this (creates version mismatch in git history):**
|
||||
>
|
||||
> - ~~commit features → then bump version → commit package.json separately~~
|
||||
>
|
||||
> This ensures that `git show v2.x.y` always contains both code changes and the version bump together.
|
||||
> The GitHub release tag will point to a commit that includes ALL changes for that version.
|
||||
|
||||
```markdown
|
||||
## [1.x.y] — YYYY-MM-DD
|
||||
```
|
||||
### 3. Regenerate lock file (REQUIRED after version bump)
|
||||
|
||||
### 3. Bump version in package.json
|
||||
**Mandatory** — skipping causes `@swc/helpers` lock mismatch and CI failures:
|
||||
|
||||
```bash
|
||||
sed -i 's/"version": "OLD"/"version": "NEW"/' package.json
|
||||
npm install
|
||||
```
|
||||
|
||||
### 4. Stage, commit, and tag
|
||||
### 4. Finalize CHANGELOG.md
|
||||
|
||||
Replace `[Unreleased]` header with the new version and date.
|
||||
Keep an empty `## [Unreleased]` section above it.
|
||||
|
||||
```markdown
|
||||
## [Unreleased]
|
||||
|
||||
---
|
||||
|
||||
## [2.x.y] — YYYY-MM-DD
|
||||
```
|
||||
|
||||
### 5. Update openapi.yaml version ⚠️ MANDATORY
|
||||
|
||||
> **CI will fail** if `docs/openapi.yaml` version ≠ `package.json` version (`check:docs-sync` enforces this).
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
VERSION=$(node -p "require('./package.json').version") && sed -i "s/ version: .*/ version: $VERSION/" docs/openapi.yaml && echo "✓ openapi.yaml → $VERSION"
|
||||
```
|
||||
|
||||
### 6. Update README.md and i18n docs
|
||||
|
||||
Run `/update-docs` workflow steps to:
|
||||
|
||||
- Update feature table rows in `README.md`
|
||||
- Sync changes to all 29 language `docs/i18n/*/README.md` files
|
||||
- Update `docs/FEATURES.md` if Settings section changed
|
||||
|
||||
### 7. Run tests
|
||||
|
||||
// turbo
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
All tests must pass before creating the PR.
|
||||
|
||||
### 8. Stage, commit, and push
|
||||
|
||||
// turbo-all
|
||||
|
||||
```bash
|
||||
git add -A
|
||||
git commit -m "feat(release): vX.Y.Z — summary of changes"
|
||||
git tag -a vX.Y.Z -m "Release vX.Y.Z — summary"
|
||||
git commit -m "chore(release): v2.x.y — summary of changes"
|
||||
git push origin release/v2.x.y
|
||||
```
|
||||
|
||||
### 5. Push to GitHub
|
||||
### 9. Open PR to main
|
||||
|
||||
```bash
|
||||
git push origin main
|
||||
git push origin vX.Y.Z
|
||||
gh pr create \
|
||||
--repo diegosouzapw/OmniRoute \
|
||||
--base main \
|
||||
--head release/v2.x.y \
|
||||
--title "chore(release): v2.x.y — summary" \
|
||||
--body "## 🚀 Release v2.x.y
|
||||
|
||||
### Changes
|
||||
...
|
||||
|
||||
### Tests
|
||||
- X/X tests pass
|
||||
|
||||
### ⚠️ After merging: run Phase 2 steps to tag, publish, and deploy."
|
||||
```
|
||||
|
||||
### 6. Publish to npm
|
||||
### 10. 🛑 STOP — Notify User & Await PR Confirmation
|
||||
|
||||
**This is a mandatory stop point.** Use `notify_user` with `BlockedOnUser: true`:
|
||||
|
||||
Inform the user:
|
||||
|
||||
- PR URL
|
||||
- Summary of changes
|
||||
- Test results
|
||||
- List of files changed
|
||||
|
||||
**DO NOT proceed to Phase 2 until the user confirms the PR looks good and merges it.**
|
||||
|
||||
---
|
||||
|
||||
## Phase 2: Post-Merge (only after user confirms)
|
||||
|
||||
> Run these steps only AFTER the user has merged the PR.
|
||||
|
||||
### 11. Pull main and create tag
|
||||
|
||||
```bash
|
||||
npm publish
|
||||
git checkout main
|
||||
git pull origin main
|
||||
git tag -a v2.x.y -m "Release v2.x.y"
|
||||
```
|
||||
|
||||
Wait for completion (prepublishOnly runs `npm run build:cli` automatically).
|
||||
|
||||
### 7. Create GitHub release
|
||||
### 12. Push tag to GitHub
|
||||
|
||||
```bash
|
||||
gh release create vX.Y.Z --title "Release vX.Y.Z" --notes-file /tmp/release_notes.md
|
||||
git push origin --tags
|
||||
```
|
||||
|
||||
### 8. Deploy to VPS (if requested)
|
||||
|
||||
See `/deploy-vps` workflow for Akamai VPS or use npm for local VPS:
|
||||
### 13. Create GitHub release
|
||||
|
||||
```bash
|
||||
ssh root@<VPS_IP> "npm install -g omniroute@X.Y.Z && pm2 restart omniroute"
|
||||
gh release create v2.x.y --title "v2.x.y — summary" --notes "..."
|
||||
```
|
||||
|
||||
### 14. 🐳 Trigger Docker Hub build (MANDATORY — keep npm and Docker in sync)
|
||||
|
||||
> **CRITICAL**: Docker Hub and npm MUST always publish the same version.
|
||||
> The Docker image is built automatically via GitHub Actions when a new tag is pushed.
|
||||
> After pushing the tag in step 11-12, **verify the workflow runs**:
|
||||
|
||||
```bash
|
||||
# Verify the Docker workflow triggered
|
||||
gh run list --repo diegosouzapw/OmniRoute --workflow docker-publish.yml --limit 3
|
||||
|
||||
# Wait for the Docker build to complete (usually 5–10 min)
|
||||
gh run watch --repo diegosouzapw/OmniRoute
|
||||
|
||||
# After completion, verify on Docker Hub:
|
||||
# https://hub.docker.com/r/diegosouzapw/omniroute/tags
|
||||
```
|
||||
|
||||
If the Docker build was not triggered automatically, trigger it manually:
|
||||
|
||||
```bash
|
||||
gh workflow run docker-publish.yml --repo diegosouzapw/OmniRoute --ref v2.x.y
|
||||
```
|
||||
|
||||
### 15. Deploy to BOTH VPS environments (MANDATORY)
|
||||
|
||||
> Always deploy to **both** environments after every release.
|
||||
> See `/deploy-vps` workflow for detailed steps.
|
||||
|
||||
```bash
|
||||
# Build and pack locally
|
||||
cd /home/diegosouzapw/dev/proxys/9router && npm run build:cli && 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"
|
||||
|
||||
# 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"
|
||||
|
||||
# Verify both
|
||||
curl -s -o /dev/null -w "LOCAL: HTTP %{http_code}\n" http://192.168.0.15:20128/
|
||||
curl -s -o /dev/null -w "AKAMAI: HTTP %{http_code}\n" http://69.164.221.35:20128/
|
||||
```
|
||||
|
||||
### 16. Clean up release branch
|
||||
|
||||
```bash
|
||||
git branch -d release/v2.x.y
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- Always run `/update-docs` BEFORE this workflow (ensures CHANGELOG and README are current)
|
||||
- The `prepublishOnly` script runs `npm run build:cli` automatically during `npm publish`
|
||||
- After npm publish, verify with `npm info omniroute version`
|
||||
- Lock file sync errors are caused by skipping `npm install` after version bump
|
||||
- Use `gh auth switch -u diegosouzapw` if git push fails with wrong account
|
||||
|
||||
## Known CI Pitfalls
|
||||
|
||||
| CI failure | Cause | Fix |
|
||||
| ------------------------------------------------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| `[docs-sync] FAIL - OpenAPI version differs from package.json` | Skipped step 5 — `docs/openapi.yaml` version not updated | Run step 5 (`sed -i ...`) and commit |
|
||||
| `[docs-sync] FAIL - CHANGELOG.md first section must be "## [Unreleased]"` | `## [Unreleased]` missing or not at top of CHANGELOG | Add `## [Unreleased]\n\n---\n` before the first versioned `## [x.y.z]` |
|
||||
| Electron Linux `.deb` build fails (`FpmTarget` error) | `fpm` Ruby gem not installed on `ubuntu-latest` runner | Already fixed in `electron-release.yml` (`gem install fpm` step) |
|
||||
| Docker Hub `502 error writing layer blob` | Transient Docker Hub network error during ARM64 push | Re-run the Docker publish workflow; no code change needed |
|
||||
|
||||
@@ -21,8 +21,8 @@ This workflow fetches all open issues from the project's GitHub repository, clas
|
||||
|
||||
// turbo
|
||||
|
||||
- Run: `gh issue list --repo <owner>/<repo> --state open --limit 100 --json number,title,labels,body,comments,createdAt,author`
|
||||
- Parse the JSON output to get a list of all open issues
|
||||
- Run: `gh issue list --repo <owner>/<repo> --state open --limit 500 --json number,title,labels,body,comments,createdAt,author`
|
||||
- Parse the JSON output to get a list of **all** open issues
|
||||
- Sort by oldest first (FIFO)
|
||||
|
||||
### 3. Classify Each Issue
|
||||
|
||||
@@ -18,7 +18,11 @@ This workflow fetches all open PRs from the project's GitHub repository, perform
|
||||
|
||||
### 2. Fetch Open Pull Requests
|
||||
|
||||
- Navigate to `https://github.com/<owner>/<repo>/pulls` and scrape all open PRs
|
||||
// turbo
|
||||
|
||||
- Run: `gh pr list --repo <owner>/<repo> --state open --limit 500 --json number,title,author,headRefName,body,createdAt,additions,deletions,files`
|
||||
- This fetches **all** open PRs without restriction. Get the diff for each with:
|
||||
`gh pr diff <NUMBER> --repo <owner>/<repo>`
|
||||
- For each open PR, collect:
|
||||
- PR number, title, author, branch, number of commits, date
|
||||
- PR description/body
|
||||
|
||||
@@ -56,13 +56,13 @@ README.pt-BR.md README.pt.md README.es.md README.fr.md README.it.md
|
||||
README.de.md README.nl.md README.sv.md README.no.md README.da.md README.fi.md
|
||||
README.ru.md README.uk-UA.md README.bg.md README.sk.md README.pl.md README.ro.md README.hu.md
|
||||
README.ar.md README.he.md README.th.md README.in.md README.id.md README.ms.md README.vi.md
|
||||
README.ja.md README.ko.md README.zh-CN.md README.phi.md
|
||||
README.ja.md README.ko.md README.zh-CN.md README.phi.md README.cs.md
|
||||
```
|
||||
|
||||
**docs/i18n/ directories (29 languages):**
|
||||
|
||||
```
|
||||
docs/i18n/{ar,bg,da,de,es,fi,fr,he,hu,id,in,it,ja,ko,ms,nl,no,phi,pl,pt,pt-BR,ro,ru,sk,sv,th,uk-UA,vi,zh-CN}/
|
||||
docs/i18n/{ar,bg,cs,da,de,es,fi,fr,he,hu,id,in,it,ja,ko,ms,nl,no,phi,pl,pt,pt-BR,ro,ru,sk,sv,th,uk-UA,vi,zh-CN}/
|
||||
Each contains: API_REFERENCE.md, ARCHITECTURE.md, CODEBASE_DOCUMENTATION.md, FEATURES.md, TROUBLESHOOTING.md, USER_GUIDE.md
|
||||
```
|
||||
|
||||
|
||||
26
.env.example
26
.env.example
@@ -142,10 +142,32 @@ GITHUB_USER_AGENT=GitHubCopilotChat/0.26.7
|
||||
ANTIGRAVITY_USER_AGENT=antigravity/1.104.0 darwin/arm64
|
||||
KIRO_USER_AGENT=AWS-SDK-JS/3.0.0 kiro-ide/1.0.0
|
||||
IFLOW_USER_AGENT=iFlow-Cli
|
||||
QWEN_USER_AGENT=google-api-nodejs-client/9.15.1
|
||||
QWEN_USER_AGENT=QwenCode/0.12.3 (linux; x64)
|
||||
CURSOR_USER_AGENT=connect-es/1.6.1
|
||||
GEMINI_CLI_USER_AGENT=google-api-nodejs-client/9.15.1
|
||||
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# CLI Fingerprint Compatibility (optional — match native CLI binary signatures)
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# When enabled, OmniRoute reorders HTTP headers and JSON body fields to match
|
||||
# the exact signature of official CLI tools, reducing account flagging risk.
|
||||
# Your proxy IP is preserved — you get both stealth AND IP masking.
|
||||
#
|
||||
# Enable per-provider:
|
||||
# CLI_COMPAT_CODEX=1
|
||||
# CLI_COMPAT_CLAUDE=1
|
||||
# CLI_COMPAT_GITHUB=1
|
||||
# CLI_COMPAT_ANTIGRAVITY=1
|
||||
# CLI_COMPAT_KIRO=1
|
||||
# CLI_COMPAT_CURSOR=1
|
||||
# CLI_COMPAT_KIMI_CODING=1
|
||||
# CLI_COMPAT_KILOCODE=1
|
||||
# CLI_COMPAT_CLINE=1
|
||||
# CLI_COMPAT_QWEN=1
|
||||
#
|
||||
# Or enable for all providers at once:
|
||||
# CLI_COMPAT_ALL=1
|
||||
|
||||
# API Key Providers (Phase 1 + Phase 4)
|
||||
# Add via Dashboard → Providers → Add API Key, or set here
|
||||
# DEEPSEEK_API_KEY=
|
||||
@@ -166,6 +188,8 @@ GEMINI_CLI_USER_AGENT=google-api-nodejs-client/9.15.1
|
||||
# Timeout settings
|
||||
# FETCH_TIMEOUT_MS=120000
|
||||
# STREAM_IDLE_TIMEOUT_MS=60000
|
||||
# API bridge timeout for /v1 proxy requests (default: 30000)
|
||||
# API_BRIDGE_PROXY_TIMEOUT_MS=120000
|
||||
|
||||
# CORS configuration (default: * allows all origins)
|
||||
# CORS_ORIGINS=*
|
||||
|
||||
3
.github/workflows/ci.yml
vendored
3
.github/workflows/ci.yml
vendored
@@ -10,6 +10,9 @@ concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
name: Lint
|
||||
|
||||
2
.github/workflows/deploy-vps.yml
vendored
2
.github/workflows/deploy-vps.yml
vendored
@@ -16,12 +16,14 @@ jobs:
|
||||
steps:
|
||||
- name: Deploy via SSH
|
||||
uses: appleboy/ssh-action@v1
|
||||
continue-on-error: true
|
||||
with:
|
||||
host: ${{ secrets.VPS_HOST }}
|
||||
username: ${{ secrets.VPS_USER }}
|
||||
key: ${{ secrets.VPS_SSH_KEY }}
|
||||
port: 22
|
||||
timeout: 30s
|
||||
command_timeout: 5m
|
||||
script: |
|
||||
echo "=== Updating OmniRoute ==="
|
||||
npm install -g omniroute@latest 2>&1
|
||||
|
||||
116
.github/workflows/docker-publish.yml
vendored
116
.github/workflows/docker-publish.yml
vendored
@@ -3,105 +3,67 @@ name: Publish to Docker Hub
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Version tag to build (e.g. 2.6.0)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build (${{ matrix.platform }})
|
||||
runs-on: ${{ matrix.runner }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- platform: linux/amd64
|
||||
platform_pair: linux-amd64
|
||||
runner: ubuntu-latest
|
||||
- platform: linux/arm64
|
||||
platform_pair: linux-arm64
|
||||
runner: ubuntu-24.04-arm
|
||||
docker:
|
||||
name: Build and Push Docker (multi-arch)
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
IMAGE_NAME: diegosouzapw/omniroute
|
||||
steps:
|
||||
- name: Checkout
|
||||
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@v4
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
uses: docker/login-action@v4
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build and push by digest
|
||||
id: build
|
||||
uses: docker/build-push-action@v6
|
||||
- name: Extract version from release tag or input
|
||||
id: version
|
||||
run: |
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
VERSION="${{ inputs.version }}"
|
||||
else
|
||||
VERSION="${GITHUB_REF_NAME}"
|
||||
VERSION="${VERSION#v}"
|
||||
fi
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Publishing Docker image: $IMAGE_NAME:$VERSION"
|
||||
|
||||
- name: Build and push multi-arch image
|
||||
uses: docker/build-push-action@v7
|
||||
with:
|
||||
context: .
|
||||
target: runner-base
|
||||
platforms: ${{ matrix.platform }}
|
||||
outputs: type=image,name=${{ env.IMAGE_NAME }},push-by-digest=true,name-canonical=true,push=true
|
||||
cache-from: type=gha,scope=omniroute-runner-base-${{ matrix.platform_pair }}
|
||||
cache-to: type=gha,mode=max,scope=omniroute-runner-base-${{ matrix.platform_pair }}
|
||||
|
||||
- name: Export digest
|
||||
run: |
|
||||
mkdir -p "${{ runner.temp }}/digests"
|
||||
digest="${{ steps.build.outputs.digest }}"
|
||||
touch "${{ runner.temp }}/digests/${digest#sha256:}"
|
||||
|
||||
- name: Upload digest
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: digests-${{ matrix.platform_pair }}
|
||||
path: ${{ runner.temp }}/digests/*
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
|
||||
merge:
|
||||
name: Merge manifest and publish tags
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
env:
|
||||
IMAGE_NAME: diegosouzapw/omniroute
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Extract version from release tag
|
||||
id: version
|
||||
run: |
|
||||
VERSION="${GITHUB_REF_NAME}"
|
||||
VERSION="${VERSION#v}"
|
||||
echo "version=$VERSION" >> "$GITHUB_OUTPUT"
|
||||
echo "Publishing Docker image version: $VERSION"
|
||||
|
||||
- name: Download digests
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: ${{ runner.temp }}/digests
|
||||
pattern: digests-*
|
||||
merge-multiple: true
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Create manifest list and push
|
||||
working-directory: ${{ runner.temp }}/digests
|
||||
run: |
|
||||
docker buildx imagetools create \
|
||||
-t "${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}" \
|
||||
-t "${{ env.IMAGE_NAME }}:latest" \
|
||||
$(printf '${{ env.IMAGE_NAME }}@sha256:%s ' *)
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
|
||||
${{ env.IMAGE_NAME }}:latest
|
||||
cache-from: type=gha
|
||||
cache-to: type=gha,mode=max
|
||||
no-cache: false
|
||||
env:
|
||||
DOCKER_BUILDKIT_INLINE_CACHE: 1
|
||||
|
||||
- name: Inspect image
|
||||
run: |
|
||||
|
||||
42
.github/workflows/electron-release.yml
vendored
42
.github/workflows/electron-release.yml
vendored
@@ -55,17 +55,18 @@ jobs:
|
||||
target: win
|
||||
ext: .exe
|
||||
- platform: macos-intel
|
||||
runner: macos-latest
|
||||
target: mac
|
||||
runner: macos-15-intel
|
||||
target: mac-x64
|
||||
ext: .dmg
|
||||
- platform: macos-arm64
|
||||
runner: macos-latest
|
||||
target: mac
|
||||
target: mac-arm64
|
||||
ext: -arm64.dmg
|
||||
- platform: linux
|
||||
runner: ubuntu-latest
|
||||
target: linux
|
||||
ext: .AppImage
|
||||
deb_ext: .deb
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@@ -78,7 +79,7 @@ jobs:
|
||||
cache: npm
|
||||
|
||||
- name: Cache node_modules
|
||||
uses: actions/cache@v4
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: node_modules
|
||||
key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
|
||||
@@ -93,12 +94,31 @@ jobs:
|
||||
JWT_SECRET: ci-build-secret-with-sufficient-length-for-validation
|
||||
run: npm run build
|
||||
|
||||
- name: Sync version in electron/package.json
|
||||
shell: bash
|
||||
run: |
|
||||
VERSION="${{ needs.validate.outputs.version }}"
|
||||
VERSION_NO_V="${VERSION#v}"
|
||||
node -e "
|
||||
const fs = require('fs');
|
||||
const pkg = JSON.parse(fs.readFileSync('electron/package.json'));
|
||||
pkg.version = '$VERSION_NO_V';
|
||||
fs.writeFileSync('electron/package.json', JSON.stringify(pkg, null, 2) + '\\n');
|
||||
"
|
||||
echo "✓ electron/package.json version set to $VERSION_NO_V"
|
||||
|
||||
- name: Install fpm (Linux .deb packaging tool)
|
||||
if: matrix.platform == 'linux'
|
||||
run: sudo gem install fpm --no-document
|
||||
|
||||
- name: Install Electron dependencies
|
||||
working-directory: electron
|
||||
run: npm install --no-audit --no-fund
|
||||
|
||||
- name: Build Electron for ${{ matrix.platform }}
|
||||
working-directory: electron
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: npm run build:${{ matrix.target }}
|
||||
|
||||
- name: Collect installers
|
||||
@@ -110,6 +130,12 @@ jobs:
|
||||
for file in *${{ matrix.ext }}; do
|
||||
[ -f "$file" ] && cp "$file" ../../release-assets/
|
||||
done
|
||||
# Linux: also copy .deb package
|
||||
if [ "${{ matrix.platform }}" = "linux" ]; then
|
||||
for file in *.deb; do
|
||||
[ -f "$file" ] && cp "$file" ../../release-assets/
|
||||
done
|
||||
fi
|
||||
# Windows: also copy portable standalone exe as OmniRoute.exe
|
||||
if [ "${{ matrix.platform }}" = "windows" ]; then
|
||||
for file in *.exe; do
|
||||
@@ -120,7 +146,7 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: electron-${{ matrix.platform }}
|
||||
path: release-assets/
|
||||
@@ -136,7 +162,7 @@ jobs:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Download all artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
path: release-assets
|
||||
merge-multiple: true
|
||||
@@ -164,14 +190,14 @@ jobs:
|
||||
draft: false
|
||||
prerelease: false
|
||||
generate_release_notes: true
|
||||
fail_on_unmatched_files: false
|
||||
files: |
|
||||
release-assets/*.dmg
|
||||
release-assets/*-arm64.dmg
|
||||
release-assets/*.exe
|
||||
release-assets/*.AppImage
|
||||
release-assets/*.deb
|
||||
release-assets/*.blockmap
|
||||
release-assets/*.source.tar.gz
|
||||
release-assets/*.source.zip
|
||||
release-assets/OmniRoute.exe
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
38
.github/workflows/npm-publish.yml
vendored
38
.github/workflows/npm-publish.yml
vendored
@@ -3,6 +3,12 @@ name: Publish to npm
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
version:
|
||||
description: "Version tag to publish (e.g. 2.6.0)"
|
||||
required: true
|
||||
type: string
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -22,21 +28,33 @@ jobs:
|
||||
node-version: 22
|
||||
registry-url: https://registry.npmjs.org
|
||||
|
||||
- name: Install dependencies
|
||||
run: npm ci
|
||||
- name: Install dependencies (skip scripts to avoid heavy build)
|
||||
run: npm install --ignore-scripts --no-audit --no-fund
|
||||
|
||||
- name: Build standalone app
|
||||
run: npm run build:cli
|
||||
|
||||
- name: Sync version from release tag
|
||||
- name: Sync version from release tag or input
|
||||
run: |
|
||||
VERSION="${GITHUB_REF_NAME}"
|
||||
# Remove 'v' prefix if present (v0.1.0 -> 0.1.0)
|
||||
VERSION="${VERSION#v}"
|
||||
if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
|
||||
VERSION="${{ inputs.version }}"
|
||||
else
|
||||
VERSION="${GITHUB_REF_NAME}"
|
||||
VERSION="${VERSION#v}"
|
||||
fi
|
||||
npm version "$VERSION" --no-git-tag-version --allow-same-version
|
||||
echo "Publishing version: $VERSION"
|
||||
|
||||
- name: Build CLI bundle (standalone app)
|
||||
env:
|
||||
JWT_SECRET: ci-build-secret-with-sufficient-length-for-validation
|
||||
run: node scripts/prepublish.mjs
|
||||
|
||||
- name: Publish to npm
|
||||
run: npm publish --access public
|
||||
run: |
|
||||
VERSION=$(node -p "require('./package.json').version")
|
||||
# Check if this version is already published — skip instead of failing with E403
|
||||
if npm view "omniroute@${VERSION}" version --silent 2>/dev/null | grep -q "^${VERSION}$"; then
|
||||
echo "️⚠️ Version ${VERSION} is already published on npm — skipping."
|
||||
exit 0
|
||||
fi
|
||||
npm publish --access public
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
|
||||
14
.gitignore
vendored
14
.gitignore
vendored
@@ -1,5 +1,10 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# project-specific directories
|
||||
.omnivscodeagent/
|
||||
omnirouteCloud/
|
||||
omnirouteSite/
|
||||
|
||||
# dependencies
|
||||
node_modules/
|
||||
/.pnp
|
||||
@@ -50,6 +55,8 @@ logs/*
|
||||
# analysis directories (generated, not tracked)
|
||||
.analysis/
|
||||
antigravity-manager-analysis/
|
||||
.sisyphus/
|
||||
.plans/
|
||||
|
||||
# docs (allow specific tracked files)
|
||||
docs/*
|
||||
@@ -77,6 +84,10 @@ docs/*
|
||||
!docs/screenshots/
|
||||
!docs/i18n/
|
||||
!docs/i18n/**
|
||||
!docs/A2A-SERVER.md
|
||||
!docs/AUTO-COMBO.md
|
||||
!docs/MCP-SERVER.md
|
||||
!docs/CLI-TOOLS.md
|
||||
|
||||
# open-sse tests
|
||||
open-sse/test/*
|
||||
@@ -89,14 +100,11 @@ test-results/
|
||||
playwright-report/
|
||||
blob-report/
|
||||
cloud/
|
||||
omnirouteCloud/
|
||||
omnirouteSite/
|
||||
|
||||
# Security Analysis (standalone project with own git)
|
||||
security-analysis/
|
||||
|
||||
# Deploy workflow (contains sensitive VPS credentials)
|
||||
.agent/workflows/deploy.md
|
||||
clipr/
|
||||
app.log
|
||||
*.tgz
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
npx lint-staged
|
||||
node scripts/check-docs-sync.mjs
|
||||
npm run test:unit
|
||||
|
||||
@@ -3,6 +3,11 @@ data/
|
||||
**/data/
|
||||
**/db.json
|
||||
|
||||
# VS Code extension test runtime (large binary, not needed in npm package)
|
||||
app/vscode-extension/
|
||||
**/data/
|
||||
**/db.json
|
||||
|
||||
# Source code (pre-built app/ is published instead)
|
||||
src/
|
||||
open-sse/
|
||||
|
||||
2037
CHANGELOG.md
2037
CHANGELOG.md
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,7 @@ WORKDIR /app
|
||||
|
||||
COPY package*.json ./
|
||||
COPY scripts/postinstall.mjs ./scripts/postinstall.mjs
|
||||
COPY scripts/native-binary-compat.mjs ./scripts/native-binary-compat.mjs
|
||||
RUN if [ -f package-lock.json ]; then npm ci --no-audit --no-fund; else npm install --no-audit --no-fund; fi
|
||||
|
||||
COPY . ./
|
||||
@@ -29,8 +30,16 @@ RUN mkdir -p /app/data
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder /app/.next/static ./.next/static
|
||||
COPY --from=builder /app/.next/standalone ./
|
||||
# Explicitly copy @swc/helpers — not always traced by standalone output but needed at runtime
|
||||
COPY --from=builder /app/node_modules/@swc/helpers ./node_modules/@swc/helpers
|
||||
# Explicitly copy pino transport dependencies — pino spawns a worker that requires
|
||||
# pino-abstract-transport at runtime; Next.js standalone trace does not capture it (#449)
|
||||
COPY --from=builder /app/node_modules/pino-abstract-transport ./node_modules/pino-abstract-transport
|
||||
COPY --from=builder /app/node_modules/pino-pretty ./node_modules/pino-pretty
|
||||
COPY --from=builder /app/node_modules/split2 ./node_modules/split2
|
||||
COPY --from=builder /app/scripts/run-standalone.mjs ./run-standalone.mjs
|
||||
COPY --from=builder /app/scripts/runtime-env.mjs ./runtime-env.mjs
|
||||
COPY --from=builder /app/scripts/bootstrap-env.mjs ./bootstrap-env.mjs
|
||||
COPY --from=builder /app/scripts/healthcheck.mjs ./healthcheck.mjs
|
||||
|
||||
EXPOSE 20128
|
||||
|
||||
460
README.md
460
README.md
@@ -2,9 +2,9 @@
|
||||
|
||||
### Never stop coding. Smart routing to **FREE & low-cost AI models** with automatic fallback.
|
||||
|
||||
_Your universal API proxy — one endpoint, 36+ providers, zero downtime. Now with **MCP & A2A** agent orchestration._
|
||||
_Your universal API proxy — one endpoint, 44+ providers, zero downtime. Now with **MCP & A2A** agent orchestration._
|
||||
|
||||
**Chat Completions • Embeddings • Image Generation • Video • Music • Audio • Reranking • MCP Server • A2A Protocol • 100% TypeScript**
|
||||
**Chat Completions • Embeddings • Image Generation • Video • Music • Audio • Reranking • **Web Search** • MCP Server • A2A Protocol • 100% TypeScript**
|
||||
|
||||
---
|
||||
|
||||
@@ -20,7 +20,7 @@ _Your universal API proxy — one endpoint, 36+ providers, zero downtime. Now wi
|
||||
|
||||
</div>
|
||||
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](README.pt-BR.md) | 🇪🇸 [Español](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [Italiano](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [Magyar](README.hu.md) | 🇮🇩 [Bahasa Indonesia](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Nederlands](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Portugal)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Polski](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [Filipino](README.phi.md)
|
||||
🌐 **Available in:** 🇺🇸 [English](README.md) | 🇧🇷 [Português (Brasil)](docs/i18n/pt-BR/README.md) | 🇪🇸 [Español](docs/i18n/es/README.md) | 🇫🇷 [Français](docs/i18n/fr/README.md) | 🇮🇹 [Italiano](docs/i18n/it/README.md) | 🇷🇺 [Русский](docs/i18n/ru/README.md) | 🇨🇳 [中文 (简体)](docs/i18n/zh-CN/README.md) | 🇩🇪 [Deutsch](docs/i18n/de/README.md) | 🇮🇳 [हिन्दी](docs/i18n/in/README.md) | 🇹🇭 [ไทย](docs/i18n/th/README.md) | 🇺🇦 [Українська](docs/i18n/uk-UA/README.md) | 🇸🇦 [العربية](docs/i18n/ar/README.md) | 🇯🇵 [日本語](docs/i18n/ja/README.md) | 🇻🇳 [Tiếng Việt](docs/i18n/vi/README.md) | 🇧🇬 [Български](docs/i18n/bg/README.md) | 🇩🇰 [Dansk](docs/i18n/da/README.md) | 🇫🇮 [Suomi](docs/i18n/fi/README.md) | 🇮🇱 [עברית](docs/i18n/he/README.md) | 🇭🇺 [Magyar](docs/i18n/hu/README.md) | 🇮🇩 [Bahasa Indonesia](docs/i18n/id/README.md) | 🇰🇷 [한국어](docs/i18n/ko/README.md) | 🇲🇾 [Bahasa Melayu](docs/i18n/ms/README.md) | 🇳🇱 [Nederlands](docs/i18n/nl/README.md) | 🇳🇴 [Norsk](docs/i18n/no/README.md) | 🇵🇹 [Português (Portugal)](docs/i18n/pt/README.md) | 🇷🇴 [Română](docs/i18n/ro/README.md) | 🇵🇱 [Polski](docs/i18n/pl/README.md) | 🇸🇰 [Slovenčina](docs/i18n/sk/README.md) | 🇸🇪 [Svenska](docs/i18n/sv/README.md) | 🇵🇭 [Filipino](docs/i18n/phi/README.md) | 🇨🇿 [Čeština](docs/i18n/cs/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -167,6 +167,16 @@ _Connect any AI-powered IDE or CLI tool through OmniRoute — free API gateway f
|
||||
- **Contributing**: See [CONTRIBUTING.md](CONTRIBUTING.md), open a PR, or pick a `good first issue`
|
||||
- **Original Project**: [9router by decolua](https://github.com/decolua/9router)
|
||||
|
||||
### 🐛 Reporting a Bug?
|
||||
|
||||
When opening an issue, please run the system-info command and attach the generated file:
|
||||
|
||||
```bash
|
||||
npm run system-info
|
||||
```
|
||||
|
||||
This generates a `system-info.txt` with your Node.js version, OmniRoute version, OS details, installed CLI tools (iflow, gemini, claude, codex, antigravity, droid, etc.), Docker/PM2 status, and system packages — everything we need to reproduce your issue quickly. Attach the file directly to your GitHub issue.
|
||||
|
||||
---
|
||||
|
||||
## 🔄 How It Works
|
||||
@@ -224,7 +234,7 @@ OpenAI uses one format, Claude (Anthropic) uses another, Gemini yet another. If
|
||||
|
||||
**How OmniRoute solves it:**
|
||||
|
||||
- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 36+ providers
|
||||
- **Unified Endpoint** — A single `http://localhost:20128/v1` serves as proxy for all 44+ providers
|
||||
- **Format Translation** — Automatic and transparent: OpenAI ↔ Claude ↔ Gemini ↔ Responses API
|
||||
- **Response Sanitization** — Strips non-standard fields (`x_groq`, `usage_breakdown`, `service_tier`) that break OpenAI SDK v1.83+
|
||||
- **Role Normalization** — Converts `developer` → `system` for non-OpenAI providers; `system` → `user` for GLM/ERNIE
|
||||
@@ -247,6 +257,7 @@ Providers like OpenAI/Codex block access from certain geographic regions. Users
|
||||
- **Connection Tests via Proxy** — Connection tests use the configured proxy (no more direct bypass)
|
||||
- **SOCKS5 Support** — Full SOCKS5 proxy support for outbound routing
|
||||
- **TLS Fingerprint Spoofing** — Browser-like TLS fingerprint via `wreq-js` to bypass bot detection
|
||||
- **🔏 CLI Fingerprint Matching** — Reorders headers and body fields to match native CLI binary signatures, drastically reducing account flagging risk. The proxy IP is preserved — you get both stealth **and** IP masking simultaneously
|
||||
|
||||
</details>
|
||||
|
||||
@@ -257,9 +268,10 @@ Not everyone can pay $20–200/month for AI subscriptions. Students, devs from e
|
||||
|
||||
**How OmniRoute solves it:**
|
||||
|
||||
- **Free Tier Providers Built-in** — Native support for 100% free providers: iFlow (8 unlimited models), Qwen (3 unlimited models), Kiro (Claude for free), Gemini CLI (180K/month free)
|
||||
- **Free Tier Providers Built-in** — Native support for 100% free providers: iFlow (5 unlimited models via OAuth: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2), Qwen (4 unlimited models: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model), Kiro (Claude + AWS Builder ID for free), Gemini CLI (180K tokens/month free)
|
||||
- **Ollama Cloud** — Cloud-hosted Ollama models at `api.ollama.com` with free "Light usage" tier; use `ollamacloud/<model>` prefix
|
||||
- **Free-Only Combos** — Chain `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/month with zero downtime
|
||||
- **NVIDIA NIM Free Credits** — 1000 free credits integrated
|
||||
- **NVIDIA NIM Free Access** — ~40 RPM dev-forever free access to 70+ models at build.nvidia.com (transitioning from credits to pure rate limits)
|
||||
- **Cost Optimized Strategy** — Routing strategy that automatically chooses the cheapest available provider
|
||||
|
||||
</details>
|
||||
@@ -308,7 +320,7 @@ Developers use Cursor, Claude Code, Codex CLI, OpenClaw, Gemini CLI, Kilo Code..
|
||||
- **CLI Tools Dashboard** — Dedicated page with one-click setup for Claude Code, Codex CLI, OpenClaw, Kilo Code, Antigravity, Cline
|
||||
- **GitHub Copilot Config Generator** — Generates `chatLanguageModels.json` for VS Code with bulk model selection
|
||||
- **Onboarding Wizard** — Guided 4-step setup for first-time users
|
||||
- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 36+ providers
|
||||
- **One endpoint, all models** — Configure `http://localhost:20128/v1` once, access 44+ providers
|
||||
|
||||
</details>
|
||||
|
||||
@@ -356,6 +368,7 @@ When a call fails, the dev doesn't know if it was a rate limit, expired token, w
|
||||
- **Translator Playground** — 4 debugging modes: Playground (format translation), Chat Tester (round-trip), Test Bench (batch), Live Monitor (real-time)
|
||||
- **Request Telemetry** — p50/p95/p99 latency + X-Request-Id tracing
|
||||
- **File-Based Logging with Rotation** — Console interceptor captures everything to JSON log with size-based rotation
|
||||
- **System Info Report** — `npm run system-info` generates `system-info.txt` with your full environment (Node version, OmniRoute version, OS, CLI tools, Docker/PM2 status). Attach it when reporting issues for instant triage.
|
||||
|
||||
</details>
|
||||
|
||||
@@ -402,7 +415,7 @@ AI isn't just chat completion. Devs need to generate images, transcribe audio, c
|
||||
- **Text-to-Video** — `/v1/videos/generations` — ComfyUI (AnimateDiff, SVD) and SD WebUI
|
||||
- **Text-to-Music** — `/v1/music/generations` — ComfyUI (Stable Audio Open, MusicGen)
|
||||
- **Audio Transcription** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM, HuggingFace, Qwen3
|
||||
- **Text-to-Speech** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, + existing providers
|
||||
- **Text-to-Speech** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, **Inworld**, **Cartesia**, **PlayHT**, + existing providers
|
||||
- **Moderations** — `/v1/moderations` — Content safety checks
|
||||
- **Reranking** — `/v1/rerank` — Document relevance reranking
|
||||
- **Responses API** — Full `/v1/responses` support for Codex
|
||||
@@ -689,6 +702,22 @@ Outcome: deep fallback depth for deadline-critical workloads
|
||||
|
||||
---
|
||||
|
||||
## 🆓 Start Free — Zero Configuration Cost
|
||||
|
||||
> Setup AI coding in minutes at **$0/month**. Connect these free accounts and use the built-in **Free Stack** combo.
|
||||
|
||||
| Step | Action | Providers Unlocked |
|
||||
| ---- | -------------------------------------------------- | ------------------------------------------------------------------ |
|
||||
| 1 | Connect **Kiro** (AWS Builder ID OAuth) | Claude Sonnet 4.5, Haiku 4.5 — **unlimited** |
|
||||
| 2 | Connect **iFlow** (Google OAuth) | kimi-k2-thinking, qwen3-coder-plus, deepseek-r1... — **unlimited** |
|
||||
| 3 | Connect **Qwen** (Device Code) | qwen3-coder-plus, qwen3-coder-flash... — **unlimited** |
|
||||
| 4 | Connect **Gemini CLI** (Google OAuth) | gemini-3-flash, gemini-2.5-pro — **180K/mo free** |
|
||||
| 5 | `/dashboard/combos` → **Free Stack ($0)** template | Round-robin all free providers automatically |
|
||||
|
||||
**Point any IDE/CLI to:** `http://localhost:20128/v1` · API Key: `any-string` · Done.
|
||||
|
||||
> **Optional extra coverage (also free):** Groq API key (30 RPM free), NVIDIA NIM (40 RPM free, 70+ models), Cerebras (1M tok/day).
|
||||
|
||||
## ⚡ Quick Start
|
||||
|
||||
### 1) Install and run
|
||||
@@ -698,6 +727,14 @@ npm install -g omniroute
|
||||
omniroute
|
||||
```
|
||||
|
||||
> **pnpm users:** Run `pnpm approve-builds -g` after install to enable native build scripts required by `better-sqlite3` and `@swc/core`:
|
||||
>
|
||||
> ```bash
|
||||
> pnpm install -g omniroute
|
||||
> pnpm approve-builds -g # Select all packages → approve
|
||||
> omniroute
|
||||
> ```
|
||||
|
||||
Dashboard opens at `http://localhost:20128` and API base URL is `http://localhost:20128/v1`.
|
||||
|
||||
| Command | Description |
|
||||
@@ -861,33 +898,177 @@ When minimized, OmniRoute lives in your system tray with quick actions:
|
||||
|
||||
## 💰 Pricing at a Glance
|
||||
|
||||
| Tier | Provider | Cost | Quota Reset | Best For |
|
||||
| ------------------- | ----------------- | ----------------------- | ---------------- | -------------------- |
|
||||
| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed |
|
||||
| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
|
||||
| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
|
||||
| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
|
||||
| **🔑 API KEY** | NVIDIA NIM | **FREE** (1000 credits) | One-time | Free tier testing |
|
||||
| | DeepSeek | Pay-per-use | None | Best price/quality |
|
||||
| | Groq | Free tier + paid | Rate limited | Ultra-fast inference |
|
||||
| | xAI (Grok) | Pay-per-use | None | Grok models |
|
||||
| | Mistral | Free tier + paid | Rate limited | European AI |
|
||||
| | OpenRouter | Pay-per-use | None | 100+ models |
|
||||
| **💰 CHEAP** | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
|
||||
| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
|
||||
| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
|
||||
| **🆓 FREE** | iFlow | $0 | Unlimited | 8 models free |
|
||||
| | Qwen | $0 | Unlimited | 3 models free |
|
||||
| | Kiro | $0 | Unlimited | Claude free |
|
||||
| Tier | Provider | Cost | Quota Reset | Best For |
|
||||
| ------------------- | --------------------------- | ------------------------- | ---------------- | --------------------------------- |
|
||||
| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed |
|
||||
| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
|
||||
| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
|
||||
| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
|
||||
| **🔑 API KEY** | NVIDIA NIM | **FREE** (dev forever) | ~40 RPM | 70+ open models |
|
||||
| | Cerebras | **FREE** (1M tok/day) | 60K TPM / 30 RPM | World's fastest |
|
||||
| | Groq | **FREE** (30 RPM) | 14.4K RPD | Ultra-fast Llama/Gemma |
|
||||
| | DeepSeek V3.2 | $0.27/$1.10 per 1M | None | Best price/quality reasoning |
|
||||
| | xAI Grok-4 Fast | **$0.20/$0.50 per 1M** 🆕 | None | Fastest + tool calling, ultralow |
|
||||
| | xAI Grok-4 (standard) | $0.20/$1.50 per 1M 🆕 | None | Reasoning flagship from xAI |
|
||||
| | Mistral | Free trial + paid | Rate limited | European AI |
|
||||
| | OpenRouter | Pay-per-use | None | 100+ models aggr. |
|
||||
| **💰 CHEAP** | GLM-5 (via Z.AI) 🆕 | $0.5/1M | Daily 10AM | 128K output, newest flagship |
|
||||
| | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
|
||||
| | MiniMax M2.5 🆕 | $0.3/1M input | 5-hour rolling | Reasoning + agentic tasks |
|
||||
| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
|
||||
| | Kimi K2.5 (Moonshot API) 🆕 | Pay-per-use | None | Direct Moonshot API access |
|
||||
| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
|
||||
| **🆓 FREE** | iFlow | **$0** | Unlimited | 5 models unlimited |
|
||||
| | Qwen | **$0** | Unlimited | 4 models unlimited |
|
||||
| | Kiro | **$0** | Unlimited | Claude Sonnet/Haiku (AWS Builder) |
|
||||
|
||||
**💡 Pro Tip:** Start with Gemini CLI (180K free/month) + iFlow (unlimited free) combo = $0 cost!
|
||||
> 🆕 **New models added (Mar 2026):** Grok-4 Fast family at $0.20/$0.50/M (benchmarked at 1143ms — 30% faster than Gemini 2.5 Flash), GLM-5 via Z.AI with 128K output, MiniMax M2.5 reasoning, DeepSeek V3.2 updated pricing, Kimi K2.5 via Moonshot direct API.
|
||||
|
||||
**💡 $0 Combo Stack — The Complete Free Setup:**
|
||||
|
||||
```
|
||||
Gemini CLI (180K/mo free)
|
||||
→ iFlow (unlimited: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1)
|
||||
→ Kiro (Claude Sonnet 4.5 + Haiku — unlimited, via AWS Builder ID)
|
||||
→ Qwen (4 models — unlimited)
|
||||
→ Groq (14.4K req/day — ultra-fast)
|
||||
→ NVIDIA NIM (70+ models — 40 RPM forever)
|
||||
```
|
||||
|
||||
**Zero cost. Never stops coding.** Configure this as one OmniRoute combo and all fallbacks happen automatically — no manual switching ever.
|
||||
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
## 🆓 Free Models — What You Actually Get
|
||||
|
||||
> All models below are **100% free with zero credit card required**. OmniRoute auto-routes between them when one quota runs out — combine them all for an unbreakable $0 combo.
|
||||
|
||||
### 🔵 CLAUDE MODELS (via Kiro — AWS Builder ID)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
| ------------------- | ------ | ------------- | --------------------- |
|
||||
| `claude-sonnet-4.5` | `kr/` | **Unlimited** | No reported daily cap |
|
||||
| `claude-haiku-4.5` | `kr/` | **Unlimited** | No reported daily cap |
|
||||
| `claude-opus-4.6` | `kr/` | **Unlimited** | Latest Opus via Kiro |
|
||||
|
||||
### 🟢 IFLOW MODELS (Free OAuth — No Credit Card)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
| ------------------ | ------ | ------------- | --------------- |
|
||||
| `kimi-k2-thinking` | `if/` | **Unlimited** | No reported cap |
|
||||
| `qwen3-coder-plus` | `if/` | **Unlimited** | No reported cap |
|
||||
| `deepseek-r1` | `if/` | **Unlimited** | No reported cap |
|
||||
| `minimax-m2.1` | `if/` | **Unlimited** | No reported cap |
|
||||
| `kimi-k2` | `if/` | **Unlimited** | No reported cap |
|
||||
|
||||
### 🟡 QWEN MODELS (Device Code Auth)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
| ------------------- | ------ | ------------- | ------------------- |
|
||||
| `qwen3-coder-plus` | `qw/` | **Unlimited** | No reported cap |
|
||||
| `qwen3-coder-flash` | `qw/` | **Unlimited** | No reported cap |
|
||||
| `qwen3-coder-next` | `qw/` | **Unlimited** | No reported cap |
|
||||
| `vision-model` | `qw/` | **Unlimited** | Multimodal (images) |
|
||||
|
||||
### 🟣 GEMINI CLI (Google OAuth)
|
||||
|
||||
| Model | Prefix | Limit | Rate Limit |
|
||||
| ------------------------ | ------ | --------------------------- | ------------- |
|
||||
| `gemini-3-flash-preview` | `gc/` | **180K tok/month** + 1K/day | Monthly reset |
|
||||
| `gemini-2.5-pro` | `gc/` | 180K/month (shared pool) | High quality |
|
||||
|
||||
### ⚫ NVIDIA NIM (Free API Key — build.nvidia.com)
|
||||
|
||||
| Tier | Daily Limit | Rate Limit | Notes |
|
||||
| ---------- | ------------ | ----------- | ------------------------------------------------------ |
|
||||
| Free (Dev) | No token cap | **~40 RPM** | 70+ models; transitioning to pure rate limits mid-2025 |
|
||||
|
||||
Popular free models: `moonshotai/kimi-k2.5` (Kimi K2.5), `z-ai/glm4.7` (GLM 4.7), `deepseek-ai/deepseek-v3.2` (DeepSeek V3.2), `nvidia/llama-3.3-70b-instruct`, `deepseek/deepseek-r1`
|
||||
|
||||
### ⚪ CEREBRAS (Free API Key — inference.cerebras.ai)
|
||||
|
||||
| Tier | Daily Limit | Rate Limit | Notes |
|
||||
| ---- | ----------------- | ---------------- | ------------------------------------------- |
|
||||
| Free | **1M tokens/day** | 60K TPM / 30 RPM | World's fastest LLM inference; resets daily |
|
||||
|
||||
Available free: `llama-3.3-70b`, `llama-3.1-8b`, `deepseek-r1-distill-llama-70b`
|
||||
|
||||
### 🔴 GROQ (Free API Key — console.groq.com)
|
||||
|
||||
| Tier | Daily Limit | Rate Limit | Notes |
|
||||
| ---- | ------------- | ---------------- | ----------------------------------------- |
|
||||
| Free | **14.4K RPD** | 30 RPM per model | No credit card; 429 on limit, not charged |
|
||||
|
||||
Available free: `llama-3.3-70b-versatile`, `gemma2-9b-it`, `mixtral-8x7b`, `whisper-large-v3`
|
||||
|
||||
> **💡 The Ultimate Free Stack:**
|
||||
>
|
||||
> ```
|
||||
> Kiro (Claude, unlimited)
|
||||
> → iFlow (5 models, unlimited)
|
||||
> → Qwen (4 models, unlimited)
|
||||
> → Gemini CLI (180K/mo)
|
||||
> → Cerebras (1M tok/day)
|
||||
> → Groq (14.4K req/day)
|
||||
> → NVIDIA NIM (40 RPM, 70+ models)
|
||||
> ```
|
||||
>
|
||||
> Configure this as an OmniRoute combo and you'll never pay for AI again.
|
||||
|
||||
## 🎙️ Free Transcription Combo
|
||||
|
||||
> Transcribe any audio/video for **$0** — Deepgram leads with $200 free, AssemblyAI $50 fallback, Groq Whisper as unlimited emergency backup.
|
||||
|
||||
| Provider | Free Credits | Best Model | Rate Limit |
|
||||
| ----------------- | ---------------------- | -------------------------------------------- | ---------------------------- |
|
||||
| 🟢 **Deepgram** | **$200 free** (signup) | `nova-3` — best accuracy, 30+ languages | No RPM limit on free credits |
|
||||
| 🔵 **AssemblyAI** | **$50 free** (signup) | `universal-3-pro` — chapters, sentiment, PII | No RPM limit on free credits |
|
||||
| 🔴 **Groq** | **Free forever** | `whisper-large-v3` — OpenAI Whisper | 30 RPM (rate limited) |
|
||||
|
||||
**Suggested combo in `/dashboard/combos`:**
|
||||
|
||||
```
|
||||
Name: free-transcription
|
||||
Strategy: Priority
|
||||
Nodes:
|
||||
[1] deepgram/nova-3 → uses $200 free first
|
||||
[2] assemblyai/universal-3-pro → fallback when Deepgram credits run out
|
||||
[3] groq/whisper-large-v3 → free forever, emergency fallback
|
||||
```
|
||||
|
||||
Then in `/dashboard/media` → **Transcription** tab: upload any audio or video file → select your combo endpoint → get transcription in supported formats.
|
||||
|
||||
## 💡 Key Features
|
||||
|
||||
OmniRoute v2.0 is built as an operational platform, not just a relay proxy.
|
||||
|
||||
### 🆕 New — ClawRouter-Inspired Improvements (Mar 2026)
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------- |
|
||||
| ⚡ **Grok-4 Fast Family** | xAI models at $0.20/$0.50/M — benchmarked 1143ms (30% faster than Gemini 2.5 Flash) |
|
||||
| 🧠 **GLM-5 via Z.AI** | 128K output context, $0.5/1M — newest flagship from the GLM family |
|
||||
| 🔮 **MiniMax M2.5** | Reasoning + agentic tasks at $0.30/1M — significant upgrade from M2.1 |
|
||||
| 🎯 **toolCalling Flag per Model** | Per-model `toolCalling: true/false` in registry — AutoCombo skips non-tool-capable models |
|
||||
| 🌍 **Multilingual Intent Detection** | PT/ZH/ES/AR keywords in AutoCombo scoring — better model selection for non-English content |
|
||||
| 📊 **Benchmark-Driven Fallbacks** | Real p95 latency from live requests feeds combo scoring — AutoCombo learns from actual data |
|
||||
| 🔁 **Request Deduplication** | Content-hash based dedup window — multi-agent safe, prevents duplicate charges |
|
||||
| 🔌 **Pluggable RouterStrategy** | Extensible `RouterStrategy` interface — add custom routing logic as plugins |
|
||||
|
||||
### 🚀 Previous v2.0.9+ — Playground, CLI Fingerprints & ACP
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
|
||||
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
|
||||
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw + 9 more), process spawner, `/api/acp/agents` endpoint |
|
||||
| 🤖 **ACP Agents Dashboard** | Debug › Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool. **OpenCode** users get a "Download opencode.json" button that auto-generates a ready-to-use config with all available models. |
|
||||
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
|
||||
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
|
||||
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
|
||||
|
||||
### 🤖 Agent & Protocol Operations (v2.0)
|
||||
|
||||
| Feature | What It Does |
|
||||
@@ -906,48 +1087,51 @@ OmniRoute v2.0 is built as an operational platform, not just a relay proxy.
|
||||
|
||||
### 🧠 Routing & Intelligence
|
||||
|
||||
| Feature | What It Does |
|
||||
| ---------------------------------- | --------------------------------------------------------------------- |
|
||||
| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free |
|
||||
| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider |
|
||||
| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Responses with schema-safe conversions |
|
||||
| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection |
|
||||
| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry |
|
||||
| 🎨 **Custom Combos** | 6 balancing strategies + fallback chain control |
|
||||
| 🌐 **Wildcard Router** | `provider/*` dynamic routing |
|
||||
| 🧠 **Thinking Budget Controls** | Passthrough, auto, custom, and adaptive reasoning limits |
|
||||
| 🔀 **Model Aliases** | Built-in + custom model aliasing and migration safety |
|
||||
| ⚡ **Background Degradation** | Route low-priority background tasks to cheaper models |
|
||||
| 💬 **System Prompt Injection** | Global behavior controls applied consistently |
|
||||
| 📄 **Responses API Compatibility** | Full `/v1/responses` support for Codex and advanced agentic workflows |
|
||||
| Feature | What It Does |
|
||||
| ---------------------------------- | ------------------------------------------------------------------------ |
|
||||
| 🎯 **Smart 4-Tier Fallback** | Auto-route: Subscription → API Key → Cheap → Free |
|
||||
| 📊 **Real-Time Quota Tracking** | Live token count + reset countdown per provider |
|
||||
| 🔄 **Format Translation** | OpenAI ↔ Claude ↔ Gemini ↔ Responses with schema-safe conversions |
|
||||
| 👥 **Multi-Account Support** | Multiple accounts per provider with intelligent selection |
|
||||
| 🔄 **Auto Token Refresh** | OAuth tokens refresh automatically with retry |
|
||||
| 🎨 **Custom Combos** | 6 balancing strategies + fallback chain control |
|
||||
| 🌐 **Wildcard Router** | `provider/*` dynamic routing |
|
||||
| 🧠 **Thinking Budget Controls** | Passthrough, auto, custom, and adaptive reasoning limits |
|
||||
| 🔀 **Model Aliases** | Built-in + custom model aliasing and migration safety |
|
||||
| ⚡ **Background Degradation** | Route low-priority background tasks to cheaper models |
|
||||
| 🧪 **Task-Aware Smart Routing** | Auto-select model by content type (coding/vision/analysis/summarization) |
|
||||
| 💬 **System Prompt Injection** | Global behavior controls applied consistently |
|
||||
| 📄 **Responses API Compatibility** | Full `/v1/responses` support for Codex and advanced agentic workflows |
|
||||
|
||||
### 🎵 Multi-Modal APIs
|
||||
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | ------------------------------------------------------------- |
|
||||
| 🖼️ **Image Generation** | `/v1/images/generations` with cloud and local backends |
|
||||
| 📐 **Embeddings** | `/v1/embeddings` for search and RAG pipelines |
|
||||
| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` (Whisper and additional providers) |
|
||||
| 🔊 **Text-to-Speech** | `/v1/audio/speech` (multiple engines/providers) |
|
||||
| 🎬 **Video Generation** | `/v1/videos/generations` (ComfyUI + SD WebUI workflows) |
|
||||
| 🎵 **Music Generation** | `/v1/music/generations` (ComfyUI workflows) |
|
||||
| 🛡️ **Moderations** | `/v1/moderations` safety checks |
|
||||
| 🔀 **Reranking** | `/v1/rerank` for relevance scoring |
|
||||
| Feature | What It Does |
|
||||
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 🖼️ **Image Generation** | `/v1/images/generations` with cloud and local backends |
|
||||
| 📐 **Embeddings** | `/v1/embeddings` for search and RAG pipelines |
|
||||
| 🎤 **Audio Transcription** | `/v1/audio/transcriptions` — 7 providers (Deepgram Nova 3, AssemblyAI, Groq Whisper, HuggingFace, ElevenLabs, OpenAI, Azure), auto-language detection, MP4/MP3/WAV support |
|
||||
| 🔊 **Text-to-Speech** | `/v1/audio/speech` — 10 providers (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) with correct error messages |
|
||||
| 🎬 **Video Generation** | `/v1/videos/generations` (ComfyUI + SD WebUI workflows) |
|
||||
| 🎵 **Music Generation** | `/v1/music/generations` (ComfyUI workflows) |
|
||||
| 🛡️ **Moderations** | `/v1/moderations` safety checks |
|
||||
| 🔀 **Reranking** | `/v1/rerank` for relevance scoring |
|
||||
| 🔍 **Web Search** 🆕 | `/v1/search` — 5 providers (Serper, Brave, Perplexity, Exa, Tavily), 6,500+ free/month, auto-failover, cache |
|
||||
|
||||
### 🛡️ Resilience, Security & Governance
|
||||
|
||||
| Feature | What It Does |
|
||||
| ----------------------------------- | ---------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breakers** | Per-model trip/recover with threshold controls |
|
||||
| 🎯 **Endpoint-Aware Models** | Custom models declare supported endpoints + API format |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore protections on retry/rate events |
|
||||
| 🧠 **Semantic + Signature Cache** | Cost/latency reduction with two cache layers |
|
||||
| ⚡ **Request Idempotency** | Duplicate protection window |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | Better compatibility with anti-bot filtered providers |
|
||||
| 🌐 **IP Filtering** | Allowlist/blocklist control for exposed deployments |
|
||||
| 📊 **Editable Rate Limits** | Configurable global/provider-level limits with persistence |
|
||||
| 🔑 **API Key Management + Scoping** | Secure key issuance/rotation and model/provider controls |
|
||||
| 🛡️ **Protected `/models`** | Optional auth gating and provider hiding for model catalog |
|
||||
| Feature | What It Does |
|
||||
| ----------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| 🔌 **Circuit Breakers** | Per-model trip/recover with threshold controls |
|
||||
| 🎯 **Endpoint-Aware Models** | Custom models declare supported endpoints + API format |
|
||||
| 🛡️ **Anti-Thundering Herd** | Mutex + semaphore protections on retry/rate events |
|
||||
| 🧠 **Semantic + Signature Cache** | Cost/latency reduction with two cache layers |
|
||||
| ⚡ **Request Idempotency** | Duplicate protection window |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | Browser-like TLS fingerprint — **reduces bot detection and account flagging** |
|
||||
| 🔏 **CLI Fingerprint Matching** | Matches native CLI request signatures — **reduces ban risk while preserving proxy IP** |
|
||||
| 🌐 **IP Filtering** | Allowlist/blocklist control for exposed deployments |
|
||||
| 📊 **Editable Rate Limits** | Configurable global/provider-level limits with persistence |
|
||||
| 🔑 **API Key Management + Scoping** | Secure key issuance/rotation and model/provider controls |
|
||||
| 🛡️ **Protected `/models`** | Optional auth gating and provider hiding for model catalog |
|
||||
|
||||
### 📊 Observability & Analytics
|
||||
|
||||
@@ -963,15 +1147,17 @@ OmniRoute v2.0 is built as an operational platform, not just a relay proxy.
|
||||
|
||||
### ☁️ Deployment & Platform
|
||||
|
||||
| Feature | What It Does |
|
||||
| ---------------------------- | -------------------------------------------------------- |
|
||||
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloud environments |
|
||||
| 💾 **Cloud Sync** | Configuration sync via cloud worker |
|
||||
| 🔄 **Backup/Restore** | Export/import and disaster recovery flows |
|
||||
| 🧙 **Onboarding Wizard** | First-run guided setup |
|
||||
| 🔧 **CLI Tools Dashboard** | One-click setup for popular coding tools |
|
||||
| 🌐 **i18n (30 languages)** | Full dashboard + docs language support with RTL coverage |
|
||||
| 📂 **Custom Data Directory** | `DATA_DIR` override for storage location |
|
||||
| Feature | What It Does |
|
||||
| ----------------------------- | -------------------------------------------------------- |
|
||||
| 🌐 **Deploy Anywhere** | Localhost, VPS, Docker, Cloud environments |
|
||||
| 💾 **Cloud Sync** | Configuration sync via cloud worker |
|
||||
| 🔄 **Backup/Restore** | Export/import and disaster recovery flows |
|
||||
| 🧙 **Onboarding Wizard** | First-run guided setup |
|
||||
| 🔧 **CLI Tools Dashboard** | One-click setup for popular coding tools |
|
||||
| 🎮 **Model Playground** | Test any provider/model/endpoint from the dashboard |
|
||||
| 🔏 **CLI Fingerprint Toggle** | Per-provider fingerprint matching in Settings > Security |
|
||||
| 🌐 **i18n (30 languages)** | Full dashboard + docs language support with RTL coverage |
|
||||
| 📂 **Custom Data Directory** | `DATA_DIR` override for storage location |
|
||||
|
||||
### Feature Deep Dive
|
||||
|
||||
@@ -1137,6 +1323,23 @@ Models:
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Codex Account Limit Management (5h + Weekly)
|
||||
|
||||
Each Codex account now has policy toggles in `Dashboard -> Providers`:
|
||||
|
||||
- `5h` (ON/OFF): enforce the 5-hour window threshold policy.
|
||||
- `Weekly` (ON/OFF): enforce the weekly window threshold policy.
|
||||
- Threshold behavior: when an enabled window reaches >=90% usage, that account is skipped.
|
||||
- Rotation behavior: OmniRoute routes to the next eligible Codex account automatically.
|
||||
- Reset behavior: when the provider `resetAt` time passes, the account becomes eligible again automatically.
|
||||
|
||||
Scenarios:
|
||||
|
||||
- `5h ON` + `Weekly ON`: account is skipped when either window reaches threshold.
|
||||
- `5h OFF` + `Weekly ON`: only weekly usage can block the account.
|
||||
- `5h ON` + `Weekly OFF`: only 5-hour usage can block the account.
|
||||
- `resetAt` passed: account re-enters rotation automatically (no manual re-enable).
|
||||
|
||||
### Gemini CLI (FREE 180K/month!)
|
||||
|
||||
```bash
|
||||
@@ -1169,7 +1372,7 @@ Models:
|
||||
<details>
|
||||
<summary><b>🔑 API Key Providers</b></summary>
|
||||
|
||||
### NVIDIA NIM (FREE 1000 credits!)
|
||||
### NVIDIA NIM (FREE developer access — 70+ models)
|
||||
|
||||
1. Sign up: [build.nvidia.com](https://build.nvidia.com)
|
||||
2. Get free API key (1000 inference credits included)
|
||||
@@ -1248,7 +1451,7 @@ Models:
|
||||
<details>
|
||||
<summary><b>🆓 FREE Providers (Emergency Backup)</b></summary>
|
||||
|
||||
### iFlow (8 FREE models)
|
||||
### iFlow (5 FREE models via OAuth)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow
|
||||
@@ -1263,7 +1466,7 @@ Models:
|
||||
if/deepseek-r1
|
||||
```
|
||||
|
||||
### Qwen (3 FREE models)
|
||||
### Qwen (4 FREE models via Device Code)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen
|
||||
@@ -1480,11 +1683,102 @@ opencode
|
||||
- OmniRoute v1.0.6+ includes fallback validation via chat completions
|
||||
- Ensure base URL includes `/v1` suffix
|
||||
|
||||
### 🔐 OAuth em Servidor Remoto (Remote OAuth Setup)
|
||||
### 🔐 OAuth on a Remote Server
|
||||
|
||||
<a name="oauth-on-a-remote-server"></a>
|
||||
<a name="oauth-em-servidor-remoto"></a>
|
||||
|
||||
> **⚠️ IMPORTANTE para usuários com OmniRoute em VPS/Docker/servidor remoto**
|
||||
> **⚠️ Important for users running OmniRoute on a VPS, Docker, or any remote server**
|
||||
|
||||
#### Why does Antigravity / Gemini CLI OAuth fail on remote servers?
|
||||
|
||||
The **Antigravity** and **Gemini CLI** providers use **Google OAuth 2.0**. Google requires the `redirect_uri` in the OAuth flow to exactly match one of the pre-registered URIs in the app's Google Cloud Console.
|
||||
|
||||
The OAuth credentials bundled in OmniRoute are registered **for `localhost` only**. When you access OmniRoute on a remote server (e.g. `https://omniroute.myserver.com`), Google rejects the authentication with:
|
||||
|
||||
```
|
||||
Error 400: redirect_uri_mismatch
|
||||
```
|
||||
|
||||
#### Solution: Configure your own OAuth credentials
|
||||
|
||||
You need to create an **OAuth 2.0 Client ID** in Google Cloud Console with your server's URI.
|
||||
|
||||
#### Step-by-step
|
||||
|
||||
**1. Open Google Cloud Console**
|
||||
|
||||
Go to: [https://console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
|
||||
|
||||
**2. Create a new OAuth 2.0 Client ID**
|
||||
|
||||
- Click **"+ Create Credentials"** → **"OAuth client ID"**
|
||||
- Application type: **"Web application"**
|
||||
- Name: anything you like (e.g. `OmniRoute Remote`)
|
||||
|
||||
**3. Add Authorized Redirect URIs**
|
||||
|
||||
In the **"Authorized redirect URIs"** field, add:
|
||||
|
||||
```
|
||||
https://your-server.com/callback
|
||||
```
|
||||
|
||||
> Replace `your-server.com` with your server's domain or IP (include the port if needed, e.g. `http://45.33.32.156:20128/callback`).
|
||||
|
||||
**4. Save and copy the credentials**
|
||||
|
||||
After creating, Google will show the **Client ID** and **Client Secret**.
|
||||
|
||||
**5. Set environment variables**
|
||||
|
||||
In your `.env` (or Docker environment variables):
|
||||
|
||||
```bash
|
||||
# For Antigravity:
|
||||
ANTIGRAVITY_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
||||
ANTIGRAVITY_OAUTH_CLIENT_SECRET=GOCSPX-your-secret
|
||||
|
||||
# For Gemini CLI:
|
||||
GEMINI_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com
|
||||
GEMINI_OAUTH_CLIENT_SECRET=GOCSPX-your-secret
|
||||
GEMINI_CLI_OAUTH_CLIENT_SECRET=GOCSPX-your-secret
|
||||
```
|
||||
|
||||
**6. Restart OmniRoute**
|
||||
|
||||
```bash
|
||||
# npm:
|
||||
npm run dev
|
||||
|
||||
# Docker:
|
||||
docker restart omniroute
|
||||
```
|
||||
|
||||
**7. Try connecting again**
|
||||
|
||||
Dashboard → Providers → Antigravity (or Gemini CLI) → OAuth
|
||||
|
||||
Google will now redirect correctly to `https://your-server.com/callback`.
|
||||
|
||||
---
|
||||
|
||||
#### Temporary workaround (without custom credentials)
|
||||
|
||||
If you don't want to set up your own credentials right now, you can still use the **manual URL flow**:
|
||||
|
||||
1. OmniRoute opens the Google authorization URL
|
||||
2. After authorizing, Google tries to redirect to `localhost` (which fails on the remote server)
|
||||
3. **Copy the full URL** from your browser's address bar (even if the page doesn't load)
|
||||
4. Paste that URL into the field shown in the OmniRoute connection modal
|
||||
5. Click **"Connect"**
|
||||
|
||||
> This works because the authorization code in the URL is valid regardless of whether the redirect page loaded.
|
||||
|
||||
---
|
||||
|
||||
<details>
|
||||
<summary><b>🇧🇷 Versão em Português</b></summary>
|
||||
|
||||
#### Por que o OAuth do Antigravity / Gemini CLI falha em servidores remotos?
|
||||
|
||||
@@ -1575,6 +1869,8 @@ Se não quiser criar credenciais próprias agora, ainda é possível usar o flux
|
||||
|
||||
---
|
||||
|
||||
</details>
|
||||
|
||||
## 🛠️ Tech Stack
|
||||
|
||||
<details>
|
||||
@@ -1669,15 +1965,9 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
|
||||
|
||||
## 📊 Star History
|
||||
|
||||
<a href="https://star-history.com/#diegosouzapw/OmniRoute&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
## Stargazers over time
|
||||
|
||||
---
|
||||
## [](https://starchart.cc/diegosouzapw/OmniRoute)
|
||||
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
|
||||
374
ZWS_README_V4.md
Normal file
374
ZWS_README_V4.md
Normal file
@@ -0,0 +1,374 @@
|
||||
# ZWS_README_V4 — 启动性能优化:HMR 泄漏修复与 Turbopack 迁移
|
||||
|
||||
## 一、如何发现问题
|
||||
|
||||
### 现象
|
||||
|
||||
- `npm run dev` 后,首次打开浏览器白屏等待 **5-22 秒**不等。
|
||||
- 运行一段时间后 Node 进程内存飙升至 **2.4 GB**,触发 Next.js 内存阈值保护强制重启。
|
||||
- 重启后 `Ready in 82.6s`(正常冷启动仅 3.4s),之后每个页面首次编译需 **7-28 秒**。
|
||||
- 日志中大量重复输出,单次会话内:
|
||||
- `[DB] SQLite database ready` 出现 **485 次**
|
||||
- `[HealthCheck] Starting proactive token health-check` 出现 **586 次**
|
||||
- `[CREDENTIALS] No external credentials file found` 出现 **432 次**
|
||||
|
||||
### 排查过程
|
||||
|
||||
1. **Terminal 日志分析**:统计关键日志出现次数,发现 DB 连接和 HealthCheck 定时器被反复创建。
|
||||
2. **代码审计**:追踪到所有受影响模块使用 `let initialized = false` 作为单例守卫——这在 Next.js dev 模式的 Webpack HMR 下会被重置。
|
||||
3. **对比**:`apiBridgeServer.ts` 使用了 `globalThis.__omnirouteApiBridgeStarted`,在日志中无重复初始化,验证了 `globalThis` 方案的有效性。
|
||||
4. **内存快照**:通过 `Get-Process node` 观察到两个 node 进程分别占用 1.7GB 和 1.0GB。
|
||||
5. **编译时间分析**:日志中 `compile:` 字段显示 Webpack 编译每个路由需 2-26 秒,对比 Turbopack 应在 0.5-3 秒。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 根因 1(P0):模块级单例在 HMR 中丢失
|
||||
|
||||
Next.js dev 模式下,Webpack HMR 会重新执行被修改(或依赖链变化)的模块。模块级 `let` 变量在每次重新执行时被重置为初始值。
|
||||
|
||||
```typescript
|
||||
// 修复前 — 每次 HMR 重新执行时 _db 重置为 null
|
||||
let _db: SqliteDatabase | null = null;
|
||||
|
||||
export function getDbInstance() {
|
||||
if (_db) return _db; // HMR 后这里永远 false
|
||||
// ... 重新打开一个新的 DB 连接(旧连接泄漏)
|
||||
}
|
||||
```
|
||||
|
||||
**受影响的模块与泄漏类型:**
|
||||
|
||||
| 模块 | 泄漏资源 | 累计次数 | 后果 |
|
||||
| ----------------------- | ---------------------- | -------- | ----------------------- |
|
||||
| `db/core.ts` | SQLite 连接 | 485 | 文件句柄泄漏 + 内存占用 |
|
||||
| `tokenHealthCheck.ts` | `setInterval` 定时器 | 586 | CPU 空转 + DB 查询风暴 |
|
||||
| `localHealthCheck.ts` | `setTimeout` 定时器链 | ~400 | 重复 HTTP 请求 + CPU |
|
||||
| `consoleInterceptor.ts` | console 方法包装 | ~400 | 日志 double-write |
|
||||
| `gracefulShutdown.ts` | SIGTERM/SIGINT handler | ~400 | 信号处理器堆叠 |
|
||||
|
||||
**级联效应**:泄漏的资源持续消耗内存和 CPU → 触发 Next.js 内存阈值保护 → 进程重启 → Webpack 从零重建模块图 → **Ready in 82.6s**。
|
||||
|
||||
### 根因 2(P0):强制使用 Webpack 而非 Turbopack
|
||||
|
||||
`scripts/run-next.mjs` 中硬编码了 `--webpack` 标志:
|
||||
|
||||
```javascript
|
||||
if (mode === "dev") {
|
||||
args.splice(2, 0, "--webpack");
|
||||
}
|
||||
```
|
||||
|
||||
Next.js 16 默认使用 Turbopack(Rust 编写的增量打包器),dev 编译速度是 Webpack 的 5-10 倍。强制回退到 Webpack 导致:
|
||||
|
||||
| 指标 | Webpack | Turbopack(预期) |
|
||||
| ----------------------- | ------- | ----------------- |
|
||||
| 首页编译 | 3.7s | ~0.5s |
|
||||
| Provider 详情页首次编译 | 22s | ~2-3s |
|
||||
| API route 首次编译 | 2-7s | ~0.3-1s |
|
||||
| 内存重启后 Ready | 82.6s | 不会触发 |
|
||||
|
||||
### 根因 3(P1):`node:crypto` 被拉入客户端 bundle
|
||||
|
||||
`src/lib/db/proxies.ts` 使用了 `import { randomUUID } from "node:crypto"`。通过 `localDb.ts` 的 re-export 链,这个 Node.js 原生模块被间接拉入客户端组件的 bundle,导致 Webpack 报错:
|
||||
|
||||
```
|
||||
UnhandledSchemeError: Reading from "node:crypto" is not handled by plugins
|
||||
Import trace: node:crypto → ./src/lib/db/proxies.ts → ./src/lib/localDb.ts → page.tsx
|
||||
```
|
||||
|
||||
Webpack 无法处理 `node:` URI scheme 前缀。`crypto`(不带 `node:` 前缀)已在 `next.config.mjs` 的 `serverExternalPackages` 中声明为服务端外部包。
|
||||
|
||||
### 根因 4(P1):Edge Runtime 编译警告刷屏
|
||||
|
||||
Next.js 16 会同时为 **Node.js** 和 **Edge** 两种运行时编译 `instrumentation.ts`。虽然 `register()` 函数内有 `process.env.NEXT_RUNTIME === "nodejs"` 的运行时守卫,但 Turbopack 在打包 Edge 版本时仍会**静态追踪**所有动态 `import()` 的依赖链:
|
||||
|
||||
```
|
||||
instrumentation.ts
|
||||
→ import("@/lib/db/secrets")
|
||||
→ @/lib/db/core.ts → fs, path, better-sqlite3
|
||||
→ @/lib/dataPaths.ts → path, os
|
||||
→ @/lib/db/migrationRunner.ts → fs, path, url
|
||||
```
|
||||
|
||||
对每个 Node.js 原生模块,Turbopack 都输出一条 "not supported in Edge Runtime" 警告。每次有新请求触发热编译时,这组 **10+ 条警告重复刷一遍**,严重污染终端输出,干扰开发调试。
|
||||
|
||||
### 根因 5(P2):启动 import 完全串行
|
||||
|
||||
`instrumentation.ts` 中 9 个 `await import()` 完全串行执行,每个都可能触发 Webpack 编译其依赖树:
|
||||
|
||||
```typescript
|
||||
await ensureSecrets(); // 串行 1
|
||||
const { initConsoleInterceptor } = await import(...); // 串行 2
|
||||
const { initGracefulShutdown } = await import(...); // 串行 3
|
||||
const { initApiBridgeServer } = await import(...); // 串行 4
|
||||
const { startBackgroundRefresh } = await import(...); // 串行 5
|
||||
const { getSettings } = await import(...); // 串行 6
|
||||
const { setCustomAliases } = await import(...); // 串行 7
|
||||
const { setDefaultFastServiceTierEnabled } = await import(...); // 串行 8
|
||||
const { initAuditLog, cleanupExpiredLogs } = await import(...); // 串行 9
|
||||
```
|
||||
|
||||
其中 4-6 互不依赖,7-8 互不依赖,完全可以并行。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复 1:globalThis 单例守卫(core.ts, tokenHealthCheck.ts, localHealthCheck.ts, consoleInterceptor.ts, gracefulShutdown.ts)
|
||||
|
||||
**原理**:`globalThis` 对象在 Node.js 进程生命周期内全局唯一,不受 Webpack 模块重新执行的影响。
|
||||
|
||||
```typescript
|
||||
// 修复后 — globalThis 在 HMR 后依然保留
|
||||
declare global {
|
||||
var __omnirouteDb: import("better-sqlite3").Database | undefined;
|
||||
}
|
||||
|
||||
function getDb() {
|
||||
return globalThis.__omnirouteDb ?? null;
|
||||
}
|
||||
function setDb(db) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
export function getDbInstance() {
|
||||
const existing = getDb();
|
||||
if (existing) return existing; // HMR 后命中缓存
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
**每个模块的具体改动:**
|
||||
|
||||
| 模块 | globalThis key | 守卫内容 |
|
||||
| ----------------------- | ----------------------------------- | ----------------------------------------------------------- |
|
||||
| `db/core.ts` | `__omnirouteDb` | SQLite 连接实例 |
|
||||
| `tokenHealthCheck.ts` | `__omnirouteTokenHC` | `{ initialized, interval }` |
|
||||
| `localHealthCheck.ts` | `__omnirouteLocalHC` | `{ initialized, sweepTimer, healthCache, sweepInProgress }` |
|
||||
| `consoleInterceptor.ts` | `__omnirouteConsoleInterceptorInit` | `boolean` |
|
||||
| `gracefulShutdown.ts` | `__omnirouteShutdownInit` | `boolean` |
|
||||
|
||||
**优点**:
|
||||
|
||||
- 零依赖,无需额外库。
|
||||
- 与 `apiBridgeServer.ts` 已有模式一致。
|
||||
- 对生产环境零影响(非 HMR 场景下行为完全相同)。
|
||||
|
||||
**缺点/注意**:
|
||||
|
||||
- `globalThis` 键名需全局唯一,使用 `__omniroute` 前缀避免冲突。
|
||||
- 需要 `declare global` 类型声明以保持 TypeScript 类型安全。
|
||||
- 生产构建中 `globalThis` 存储略冗余(但仅是一个对象引用,几乎零开销)。
|
||||
|
||||
### 修复 2:支持通过环境变量切换 Turbopack(run-next.mjs)
|
||||
|
||||
```javascript
|
||||
// 修复后 — 默认仍用 webpack(保持原有行为),设置环境变量可启用 Turbopack
|
||||
if (mode === "dev" && process.env.OMNIROUTE_USE_TURBOPACK !== "1") {
|
||||
args.splice(2, 0, "--webpack");
|
||||
}
|
||||
```
|
||||
|
||||
**默认行为不变**:dev 模式仍使用 Webpack,与修复前完全一致。设置 `OMNIROUTE_USE_TURBOPACK=1` 可切换到 Turbopack 以获得更快的 dev 编译速度。
|
||||
|
||||
**优点**:
|
||||
|
||||
- 零风险:不改变任何人的现有体验。
|
||||
- 需要时设置 `OMNIROUTE_USE_TURBOPACK=1` 即可获得 5-10 倍编译加速。
|
||||
- `next.config.mjs` 中已有 `turbopack.resolveAlias` 配置,说明项目已在准备 Turbopack 迁移。
|
||||
|
||||
**缺点/注意**:
|
||||
|
||||
- Turbopack 对某些 Webpack 特定配置(如自定义 externals 函数)的支持方式不同,启用前需测试兼容性。
|
||||
- 默认走 Webpack 意味着不主动启用 Turbopack 的用户无法享受编译加速。
|
||||
|
||||
### 修复 3:`node:crypto` → `crypto`(proxies.ts, errorResponse.ts)
|
||||
|
||||
```typescript
|
||||
// 修复前
|
||||
import { randomUUID } from "node:crypto";
|
||||
|
||||
// 修复后
|
||||
import { randomUUID } from "crypto";
|
||||
```
|
||||
|
||||
**优点**:
|
||||
|
||||
- `crypto`(无 `node:` 前缀)已在 `next.config.mjs` 的 `serverExternalPackages` 列表中,Webpack/Turbopack 会正确将其标记为外部包。
|
||||
- 消除 `UnhandledSchemeError` 构建失败。
|
||||
- Node.js 中 `crypto` 和 `node:crypto` 解析到同一模块。
|
||||
|
||||
**缺点**:
|
||||
|
||||
- 无。`crypto` 是 Node.js 内建模块,两种写法功能完全等价。
|
||||
|
||||
### 修复 4:分离 Edge/Node.js Instrumentation(instrumentation.ts → instrumentation-node.ts)
|
||||
|
||||
**问题**:`instrumentation.ts` 中所有 Node.js 逻辑(`ensureSecrets`、DB 初始化、审计日志等)虽然只在 `NEXT_RUNTIME === "nodejs"` 时执行,但 Turbopack 编译 Edge 版本时仍静态追踪其 import 链,对每个 `fs`/`path`/`os`/`better-sqlite3` 等原生模块输出警告。
|
||||
|
||||
**方案**:将所有 Node.js 专属逻辑提取到 `src/instrumentation-node.ts`,主文件通过**计算的 import 路径**引入,阻止 Turbopack 静态解析:
|
||||
|
||||
```typescript
|
||||
// src/instrumentation.ts — 精简后仅 ~20 行
|
||||
export async function register() {
|
||||
if (process.env.NEXT_RUNTIME === "nodejs") {
|
||||
// 拼接路径阻止 Turbopack 在 Edge 编译时静态解析模块依赖
|
||||
const nodeMod = "./instrumentation-" + "node";
|
||||
const { registerNodejs } = await import(nodeMod);
|
||||
await registerNodejs();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// src/instrumentation-node.ts — 包含全部 Node.js 启动逻辑
|
||||
export async function registerNodejs(): Promise<void> {
|
||||
await ensureSecrets();
|
||||
// initConsoleInterceptor, initGracefulShutdown, initApiBridgeServer, ...
|
||||
// (原 instrumentation.ts 的完整 Node.js 逻辑)
|
||||
}
|
||||
```
|
||||
|
||||
**关键技术**:`"./instrumentation-" + "node"` 是运行时拼接的字符串,Turbopack 无法在编译期确定其值,因此**不会追踪**该 import 的依赖树。Node.js 运行时则正常解析该路径并执行。
|
||||
|
||||
**优点**:
|
||||
|
||||
- Edge 编译时完全跳过 Node.js 模块追踪,**10+ 条重复警告全部消除**。
|
||||
- Node.js 运行时行为与修复前完全一致。
|
||||
- 启动时间从 **13.9s → 1.25s**(Turbopack 不再在 Edge 编译中处理 Node.js 模块图)。
|
||||
|
||||
**缺点/注意**:
|
||||
|
||||
- 新增一个文件 `instrumentation-node.ts`,需同步维护。
|
||||
- 计算 import 路径是有意为之的 bundler 逃逸技巧,需加注释说明原因防止后续重构时被"优化"回静态字符串。
|
||||
|
||||
### 修复 5:并行化 instrumentation.ts 中的启动 import
|
||||
|
||||
```typescript
|
||||
// 修复后 — 4 个独立模块并行导入
|
||||
const [
|
||||
{ initGracefulShutdown },
|
||||
{ initApiBridgeServer },
|
||||
{ startBackgroundRefresh },
|
||||
{ getSettings },
|
||||
] = await Promise.all([
|
||||
import("@/lib/gracefulShutdown"),
|
||||
import("@/lib/apiBridgeServer"),
|
||||
import("@/domain/quotaCache"),
|
||||
import("@/lib/db/settings"),
|
||||
]);
|
||||
|
||||
// 2 个 open-sse 模块也并行导入
|
||||
const [{ setCustomAliases }, { setDefaultFastServiceTierEnabled }] = await Promise.all([
|
||||
import("@omniroute/open-sse/services/modelDeprecation.ts"),
|
||||
import("@omniroute/open-sse/executors/codex.ts"),
|
||||
]);
|
||||
```
|
||||
|
||||
**优点**:
|
||||
|
||||
- `consoleInterceptor` 仍保持第一个(必须在任何日志前初始化)。
|
||||
- 后续 4 个无依赖模块并行加载,节省 3 次串行等待。
|
||||
- open-sse 的 2 个模块也并行加载。
|
||||
|
||||
**缺点**:
|
||||
|
||||
- 并行 import 的错误堆栈略复杂(Promise.all 中某一个失败会 reject 整个组)。
|
||||
- 这里的 compliance 模块仍保持独立 try/catch 串行,因为它有自己的错误处理逻辑。
|
||||
|
||||
---
|
||||
|
||||
## 四、预期效果
|
||||
|
||||
| 指标 | 修复前 | 修复后(预期) |
|
||||
| ----------------------------- | ------------------------- | ------------------------ |
|
||||
| DB 连接创建次数 | 485 次/会话 | 1 次 |
|
||||
| HealthCheck 定时器 | 586 个泄漏 | 1 个 |
|
||||
| 信号处理器注册 | ~400 次重复 | 1 次 |
|
||||
| Console 拦截层数 | ~400 层嵌套 | 1 层 |
|
||||
| 内存使用峰值 | 2.4 GB → OOM 重启 | 预期 < 500 MB |
|
||||
| 冷启动 Ready | 3.4s | ~3s(略快) |
|
||||
| 内存重启 Ready | 82.6s | 不再触发内存重启 |
|
||||
| Login 页首次编译 | 3.7s | ~0.5s (需启用 Turbopack) |
|
||||
| Provider 详情页首次编译 | 22s | ~2-3s (需启用 Turbopack) |
|
||||
| `node:crypto` 构建错误 | 反复出现 | 消除 |
|
||||
| Edge Runtime 编译警告 | 每次热编译刷出 10+ 条 | **0 条** |
|
||||
| instrumentation 启动耗时 | 13.9s(含 Edge 模块追踪) | **1.25s** |
|
||||
| instrumentation import 并行度 | 9 次串行 import | 3 批并行 import |
|
||||
|
||||
---
|
||||
|
||||
## 五、涉及文件清单
|
||||
|
||||
| 区域 | 文件 | 改动类型 |
|
||||
| ------------------- | ------------------------------- | ------------------------------------------------------------------ |
|
||||
| DB 单例 | `src/lib/db/core.ts` | `let _db` → `globalThis.__omnirouteDb` |
|
||||
| Token 健康检查 | `src/lib/tokenHealthCheck.ts` | `let initialized` → `globalThis.__omnirouteTokenHC` |
|
||||
| 本地节点健康检查 | `src/lib/localHealthCheck.ts` | `let initialized` → `globalThis.__omnirouteLocalHC` |
|
||||
| Console 拦截 | `src/lib/consoleInterceptor.ts` | `let initialized` → `globalThis.__omnirouteConsoleInterceptorInit` |
|
||||
| 优雅关停 | `src/lib/gracefulShutdown.ts` | 新增 `globalThis.__omnirouteShutdownInit` 守卫 |
|
||||
| Dev 启动脚本 | `scripts/run-next.mjs` | 新增 `OMNIROUTE_USE_TURBOPACK=1` 开关 |
|
||||
| Proxy 注册表 | `src/lib/db/proxies.ts` | `node:crypto` → `crypto` |
|
||||
| API 错误响应 | `src/lib/api/errorResponse.ts` | `node:crypto` → `crypto` |
|
||||
| 启动钩子(主入口) | `src/instrumentation.ts` | 精简为 ~20 行,计算 import 路径阻止 Edge 追踪 |
|
||||
| 启动钩子(Node.js) | `src/instrumentation-node.ts` | 新文件,承载全部 Node.js 启动逻辑 + `Promise.all` 并行 |
|
||||
|
||||
---
|
||||
|
||||
## 六、回退方案
|
||||
|
||||
- **启用 Turbopack**:设置 `OMNIROUTE_USE_TURBOPACK=1` 环境变量;不设置则默认使用 Webpack(原有行为不变)。
|
||||
- **globalThis 方案异常**:所有 globalThis key 都以 `__omniroute` 为前缀,可通过 `delete globalThis.__omnirouteDb` 等方式手动重置。
|
||||
- **Edge 警告回退**:若 `instrumentation-node.ts` 拆分导致问题,可将其内容合并回 `instrumentation.ts`,恢复为直接 `import()` 调用(警告会重新出现但不影响功能)。
|
||||
- **生产环境**:以上修复对生产构建无负面影响——生产环境不存在 HMR,globalThis 单例仅在首次调用时初始化一次。计算 import 路径在 `next build` 时由 Node.js 正常解析,不影响打包产物。
|
||||
|
||||
---
|
||||
|
||||
## 七、单元测试与备份恢复(pre-commit 验证通过)
|
||||
|
||||
为保证提交前必须通过验证(不再使用 `--no-verify`),对以下失败用例与生产逻辑做了修复与加固。
|
||||
|
||||
### 问题与根因
|
||||
|
||||
| 失败项 | 根因 |
|
||||
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| bootstrap-env 4 个用例 | Windows 上 DATA_DIR 解析用 `APPDATA`/`homedir()`,测试只设了 `HOME`,脚本读不到测试用的 `.env`。 |
|
||||
| domain-persistence costRules 2 个用例 | `core` 在首次 import 时缓存 `DATA_DIR`;测试每测一个 tmpDir 并在 afterEach 删目录,导致后续 describe 使用的 DB 路径已被删,读写得到 0。 |
|
||||
| fixes-p1 restoreDbBackup | 测试在 DB 仍打开时写 stale 侧文件;`restoreDbBackup` 内 pre-restore 备份未 await 就关库,Windows 上句柄未及时释放,unlink 报 EBUSY。 |
|
||||
| fixes-p1 resetStorage 及后续用例 | 上一测留下 DB 打开,下一测 `resetStorage()` 删目录时文件仍被占用,EBUSY。 |
|
||||
|
||||
### 修复 6:bootstrap-env 测试(tests/unit/bootstrap-env.test.mjs)
|
||||
|
||||
在每个用例的 `withTempEnv` 回调开头增加 `process.env.DATA_DIR = dataDir`,使脚本在任意平台(含 Windows)都使用测试临时目录,而不是依赖 `HOME`/`APPDATA`。
|
||||
|
||||
### 修复 7:domain-persistence 测试(tests/unit/domain-persistence.test.mjs)
|
||||
|
||||
- **单例 tmpDir**:全文件共用一个 `fileTmpDir`,在模块加载时创建并设置 `process.env.DATA_DIR`,与 `core` 首次加载时缓存的路径一致。
|
||||
- **每测清 DB 不清目录**:`beforeEach` 中 `resetDbInstance()` 后删除 `storage.sqlite` 及其 `-wal`/`-shm`/`-journal`,保证每测干净 DB,不在 afterEach 删目录,避免路径失效。
|
||||
- **收尾**:`after()` 中恢复 `DATA_DIR` 并删除 `fileTmpDir`。
|
||||
- **costRules 断言**:改为小容差精确校验(`assertAlmostEqual`),继续验证 `4.5` / `4.0` 这类业务关键值,避免把真实累计错误放过去。
|
||||
|
||||
### 修复 8:fixes-p1 测试(tests/unit/fixes-p1.test.mjs)
|
||||
|
||||
- **restoreDbBackup 用例**:在写入 stale 侧文件前调用 `core.resetDbInstance()`,避免 DB 仍打开时写 `-wal`/`-shm` 触发 Windows 锁错误。
|
||||
- **Windows 跳过**:该用例在 Windows 上仍使用 `test(..., { skip: isWindows })`。原因不是业务逻辑不支持 Windows,而是 better-sqlite3 关闭后底层句柄释放存在时序抖动,这条真实 sidecar 集成测试容易退化成不稳定的文件锁测试;Linux/macOS 上照常运行。
|
||||
- **核心兜底测试**:新增平台无关的 `unlinkFileWithRetry` 单测,直接模拟 `EBUSY` / `EPERM` 后重试并最终成功,确保 Windows 相关的重试删除逻辑被稳定覆盖,而不是完全依赖 flaky 的真实文件锁时序。
|
||||
- **resetStorage**:改为 async,对 `rmSync(TEST_DATA_DIR)` 做最多 10 次、间隔 100ms 的 EBUSY/EPERM 重试,避免下一测因上一测句柄未释放而失败。
|
||||
|
||||
### 修复 9:备份恢复逻辑(src/lib/db/backup.ts)
|
||||
|
||||
- **pre-restore 备份改为同步等待**:在 `restoreDbBackup` 内用内联逻辑做 pre-restore 备份并 `await` 完成,再调用 `resetDbInstance()`,避免异步 backup 未结束就关库导致后续 unlink 失败。
|
||||
- **节流语义保持一致**:pre-restore 备份成功后补回 `_lastBackupAt = Date.now()`,避免恢复后紧接着又触发一轮额外自动备份。
|
||||
- **关库后短延迟**:`resetDbInstance()` 后 `await new Promise(r => setTimeout(r, 500))`,再执行 unlink,给 Windows 等平台释放句柄留时间。
|
||||
- **unlink 重试**:将主库及 `-wal`/`-shm`/`-journal` 的删除提取为 `unlinkFileWithRetry`,统一做最多 10 次、间隔 100ms 的 EBUSY/EPERM 重试,提高恢复流程在锁释放较慢环境下的成功率,也便于单测直接覆盖重试逻辑。
|
||||
|
||||
### 涉及文件(本节)
|
||||
|
||||
| 区域 | 文件 | 改动类型 |
|
||||
| -------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
|
||||
| 单元测试 | `tests/unit/bootstrap-env.test.mjs` | 各用例内设置 `process.env.DATA_DIR = dataDir` |
|
||||
| 单元测试 | `tests/unit/domain-persistence.test.mjs` | 单例 tmpDir、beforeEach 清 DB 文件、after 删目录;costRules 改为小容差精确断言 |
|
||||
| 单元测试 | `tests/unit/fixes-p1.test.mjs` | restoreDbBackup 前 resetDbInstance、Windows skip 说明、resetStorage 重试、`unlinkFileWithRetry` 核心单测 |
|
||||
| 备份恢复 | `src/lib/db/backup.ts` | pre-restore 内联并 await、恢复 `_lastBackupAt` 节流语义、关库后 500ms 延迟、抽取 `unlinkFileWithRetry` 重试删除 |
|
||||
332
ZWS_README_V5.md
Normal file
332
ZWS_README_V5.md
Normal file
@@ -0,0 +1,332 @@
|
||||
# ZWS_README_V5 — 按协议配置模型兼容性 + 前端性能优化
|
||||
|
||||
V4 内容(HMR 泄漏修复、Edge 警告消除、测试稳定性)已完成;V5 在 V4 基础上实现**按协议维度配置模型兼容性**,新增前端查找性能优化与类型安全改进。
|
||||
|
||||
---
|
||||
|
||||
## 一、如何发现问题
|
||||
|
||||
### 现象
|
||||
|
||||
- 同一模型被 **OpenAI Chat Completions**、**OpenAI Responses API**、**Anthropic Messages** 三种客户端请求形态调用时,V2 的兼容性开关(工具 ID 9 位、不保留 developer 角色)是**全局生效**的——无法为不同协议设置不同的兼容策略。
|
||||
- 例如:用户希望 OpenAI Responses API 请求时不保留 developer 角色(MiniMax 422 修复),但 OpenAI Chat Completions 请求时保留。V2 下只能二选一。
|
||||
- 前端兼容性弹层未标明当前配置对应哪种协议,容易误导。
|
||||
- 前端组件中 `Array.find()` 在每次渲染时对 customModels 和 modelCompatOverrides 做 O(n) 线性扫描,模型数量多时存在不必要的性能开销。
|
||||
- `ModelCompatPatch` 类型定义与运行时逻辑不一致:`preserveOpenAIDeveloperRole` 字段需要支持 `null`(表示取消设置/恢复默认),但类型仅允许 `boolean`。
|
||||
|
||||
### 排查过程
|
||||
|
||||
1. **需求分析**:梳理 `detectFormat(body)` 返回的三种协议键(`openai`、`openai-responses`、`claude`),确认每种协议对 developer 角色和 tool call ID 的需求不同。
|
||||
2. **数据模型设计**:在现有 `normalizeToolCallId` / `preserveOpenAIDeveloperRole` 顶层字段基础上,设计 `compatByProtocol` 嵌套结构,按协议键细分。
|
||||
3. **构建问题**:客户端 `"use client"` 组件直接从 `@/lib/localDb` 引入常量时,间接拉入了 `node:crypto`(经由 `db/proxies.ts`),触发 Webpack `UnhandledSchemeError`。需将常量拆到 `shared/` 层。
|
||||
4. **前端性能**:通过 React DevTools 和代码审计发现 `effectiveNormalizeForProtocol` 等函数每次调用都对数组做 `find()`,在渲染列表时存在 O(n²) 的隐患。
|
||||
|
||||
---
|
||||
|
||||
## 二、根因分析
|
||||
|
||||
### 根因 1(P0):兼容选项无协议维度
|
||||
|
||||
V2 的 `normalizeToolCallId` / `preserveOpenAIDeveloperRole` 存储在模型级别的顶层字段,无法区分请求来源协议。`chatCore.ts` 中的 getter 函数只接收 `(providerId, modelId)` 两个参数,不感知当前请求的 `sourceFormat`。
|
||||
|
||||
**影响**:跨协议场景下用户只能设置一个全局值,无法精确控制。
|
||||
|
||||
### 根因 2(P1):客户端构建拉入 Node.js 模块
|
||||
|
||||
`page.tsx`("use client")→ `@/lib/localDb` → `db/proxies.ts` → `import { randomUUID } from "node:crypto"`
|
||||
|
||||
Webpack 无法处理 `node:` URI scheme,报 `UnhandledSchemeError`。虽然 V4 已将 `node:crypto` → `crypto` 修复了 `proxies.ts`,但 `localDb.ts` 的 barrel export 链仍然存在风险——客户端组件不应引入任何可能传递到 Node.js 模块的路径。
|
||||
|
||||
### 根因 3(P2):前端查找性能
|
||||
|
||||
`effectiveNormalizeForProtocol`、`effectivePreserveForProtocol`、`anyNormalizeCompatBadge`、`anyNoPreserveCompatBadge` 四个函数每次调用都使用 `Array.find()` 在 `customModels` 和 `modelCompatOverrides` 数组中查找目标模型。在模型列表渲染时,每个模型行会调用多次这些函数,导致 O(n × m) 的查找开销(n = 模型数,m = 每行调用次数)。
|
||||
|
||||
### 根因 4(P2):类型定义与运行时不一致
|
||||
|
||||
```typescript
|
||||
// V3 暂存区版本(有问题)
|
||||
export type ModelCompatPatch = Partial<
|
||||
Pick<
|
||||
ModelCompatOverride,
|
||||
"normalizeToolCallId" | "preserveOpenAIDeveloperRole" | "compatByProtocol"
|
||||
>
|
||||
>;
|
||||
```
|
||||
|
||||
`ModelCompatOverride.preserveOpenAIDeveloperRole` 类型为 `boolean | undefined`,但 `mergeModelCompatOverride()` 内部有 `=== null` 判断(用于取消设置/恢复默认),类型层面无法覆盖。
|
||||
|
||||
---
|
||||
|
||||
## 三、修复方案
|
||||
|
||||
### 修复 1:`compatByProtocol` 存储与读取(models.ts)
|
||||
|
||||
**新增数据结构**:
|
||||
|
||||
```typescript
|
||||
type CompatByProtocolMap = Partial<Record<ModelCompatProtocolKey, ModelCompatPerProtocol>>;
|
||||
|
||||
export type ModelCompatOverride = {
|
||||
id: string;
|
||||
normalizeToolCallId?: boolean;
|
||||
preserveOpenAIDeveloperRole?: boolean;
|
||||
compatByProtocol?: CompatByProtocolMap; // 新增
|
||||
};
|
||||
```
|
||||
|
||||
**读取优先级链**(适用于 `getModelNormalizeToolCallId` 和 `getModelPreserveOpenAIDeveloperRole`):
|
||||
|
||||
```
|
||||
compatByProtocol[sourceFormat].field → 顶层 field → 默认值
|
||||
```
|
||||
|
||||
1. 若 `sourceFormat` 属于已知协议键(`openai` / `openai-responses` / `claude`),且 `compatByProtocol[sourceFormat]` 中存在目标字段,使用该值。
|
||||
2. 否则回退到顶层字段。
|
||||
3. 顶层字段也不存在时使用默认值(normalizeToolCallId=false,preserveOpenAIDeveloperRole=undefined)。
|
||||
|
||||
**深度合并逻辑** `deepMergeCompatByProtocol()`:
|
||||
|
||||
- 对每个协议键,逐字段合并而非覆盖。
|
||||
- `normalizeToolCallId=false` 时删除该字段(不存储 false,减少冗余)。
|
||||
- 合并后若整个协议条目为空对象,删除该协议条目。
|
||||
- 协议键通过 `isCompatProtocolKey()` 白名单校验,拒绝未知键。
|
||||
|
||||
**Getter 签名扩展**(向后兼容,第三参数可选):
|
||||
|
||||
```typescript
|
||||
export function getModelNormalizeToolCallId(
|
||||
providerId: string,
|
||||
modelId: string,
|
||||
sourceFormat?: string | null
|
||||
): boolean;
|
||||
|
||||
export function getModelPreserveOpenAIDeveloperRole(
|
||||
providerId: string,
|
||||
modelId: string,
|
||||
sourceFormat?: string | null
|
||||
): boolean | undefined;
|
||||
```
|
||||
|
||||
**优点**:
|
||||
|
||||
- 完全向后兼容:无 `sourceFormat` 参数时行为与 V2 完全一致。
|
||||
- 协议键白名单校验防止存储污染。
|
||||
- 深度合并保留未变更协议的配置。
|
||||
|
||||
**缺点/注意**:
|
||||
|
||||
- JSON 存储体积略增(每个模型最多增加 3 个协议条目)。
|
||||
- 新增 ~80 行 TypeScript 代码。
|
||||
|
||||
### 修复 2:请求管线传入 sourceFormat(chatCore.ts)
|
||||
|
||||
```typescript
|
||||
const normalizeToolCallId = getModelNormalizeToolCallId(
|
||||
provider || "",
|
||||
model || "",
|
||||
sourceFormat // 新增第三参
|
||||
);
|
||||
const preserveDeveloperRole = getModelPreserveOpenAIDeveloperRole(
|
||||
provider || "",
|
||||
model || "",
|
||||
sourceFormat // 新增第三参
|
||||
);
|
||||
```
|
||||
|
||||
`sourceFormat` 由已有的 `detectFormat(body)` 返回,无需新增检测逻辑。
|
||||
|
||||
**优点**:
|
||||
|
||||
- 改动仅 2 行,精准传参。
|
||||
- 不影响其他 handler(embeddings、imageGeneration 等不涉及 developer 角色和 tool call ID)。
|
||||
|
||||
### 修复 3:API 路由支持 compatByProtocol(route.ts)
|
||||
|
||||
**PUT 请求体扩展**:
|
||||
|
||||
- 解构 `compatByProtocol` 并传入 `updateCustomModel()`。
|
||||
- `compatOnly` 判断扩展:仅含 `provider` + `modelId` + 兼容字段时,走 `mergeModelCompatOverride()` 路径。
|
||||
- 使用 `ModelCompatPatch` 类型替代行内类型定义,统一类型来源。
|
||||
|
||||
**Zod 校验 schema**:
|
||||
|
||||
```typescript
|
||||
const modelCompatPerProtocolSchema = z.object({
|
||||
normalizeToolCallId: z.boolean().optional(),
|
||||
preserveOpenAIDeveloperRole: z.boolean().optional(),
|
||||
}).strict(); // strict: 拒绝额外字段
|
||||
|
||||
compatByProtocol: z
|
||||
.record(z.enum(["openai", "openai-responses", "claude"]), modelCompatPerProtocolSchema)
|
||||
.optional(),
|
||||
```
|
||||
|
||||
**优点**:
|
||||
|
||||
- `.strict()` 防止客户端注入额外字段。
|
||||
- `z.enum()` 限定协议键,与后端白名单一致。
|
||||
- 仅传 `compatByProtocol` 即可更新,前端无需拼装完整模型对象。
|
||||
|
||||
### 修复 4:客户端安全常量拆分(modelCompat.ts)
|
||||
|
||||
**新增** `src/shared/constants/modelCompat.ts`:
|
||||
|
||||
```typescript
|
||||
export const MODEL_COMPAT_PROTOCOL_KEYS = ["openai", "openai-responses", "claude"] as const;
|
||||
export type ModelCompatProtocolKey = (typeof MODEL_COMPAT_PROTOCOL_KEYS)[number];
|
||||
```
|
||||
|
||||
- 不依赖 Node.js / DB 代码,客户端组件可安全引入。
|
||||
- `models.ts` 从此模块引入并再导出。
|
||||
- `localDb.ts` 新增 `ModelCompatPatch` 类型导出(供 route.ts 使用),不导出协议常量。
|
||||
- `page.tsx` 改为从 `@/shared/constants/modelCompat` 引入。
|
||||
|
||||
**优点**:
|
||||
|
||||
- 彻底切断客户端 → localDb → db → proxies → node:crypto 的依赖链。
|
||||
- 协议键定义单一来源(Single Source of Truth)。
|
||||
|
||||
### 修复 5:前端协议选择器与按协议解析(page.tsx)
|
||||
|
||||
**ModelCompatPopover 重构**:
|
||||
|
||||
- 新增协议下拉选择器(`<select>`),可选 OpenAI Chat / OpenAI Responses / Anthropic Messages。
|
||||
- 两个开关(工具 ID 9 位、不保留 developer)**针对选中协议**生效。
|
||||
- 选择 Claude 协议时隐藏 developer 角色开关(developer 仅对 OpenAI 系有意义)。
|
||||
- 保存时以 `{ compatByProtocol: { [protocol]: payload } }` 形式提交,后端按协议合并。
|
||||
- 深色模式适配:下拉框使用 `bg-white dark:bg-zinc-800`、`text-zinc-900 dark:text-zinc-100`。
|
||||
|
||||
**Props 接口重构**:
|
||||
|
||||
旧接口(4 个独立值/回调):
|
||||
|
||||
```typescript
|
||||
(normalizeToolCallId, preserveDeveloperRole, onNormalizeChange, onPreserveChange);
|
||||
```
|
||||
|
||||
新接口(3 个函数式 props):
|
||||
|
||||
```typescript
|
||||
effectiveModelNormalize: (protocol: string) => boolean
|
||||
effectiveModelPreserveDeveloper: (protocol: string) => boolean
|
||||
onCompatPatch: (protocol: string, payload: {...}) => void
|
||||
```
|
||||
|
||||
所有消费方(`ModelRow`、`PassthroughModelRow`、`CustomModelsSection`、`CompatibleModelsSection`)已同步更新。
|
||||
|
||||
**角标显示逻辑**:
|
||||
|
||||
- `anyNormalizeCompatBadge()`:任意协议或顶层存在 `normalizeToolCallId=true` 即显示「ID×9」角标。
|
||||
- `anyNoPreserveCompatBadge()`:任意协议或顶层存在 `preserveOpenAIDeveloperRole=false` 即显示「不保留」角标。
|
||||
|
||||
**CustomModelsSection 增强**:
|
||||
|
||||
- 新增 `modelCompatOverrides` 状态,从 API 响应中获取。
|
||||
- 新增 `saveCustomCompat()` 函数,支持仅传 `compatByProtocol` 的独立保存。
|
||||
|
||||
### 修复 6:前端 Map 查找性能优化(page.tsx)
|
||||
|
||||
**问题**:`effectiveNormalizeForProtocol` 等函数对 `customModels` 和 `modelCompatOverrides` 用 `Array.find()` 做 O(n) 查找,在列表渲染时每个模型行多次调用。
|
||||
|
||||
**方案**:使用 `useMemo` + `Map` 将数组预建为 O(1) 查找表。
|
||||
|
||||
```typescript
|
||||
type CompatModelMap = Map<string, CompatModelRow>;
|
||||
|
||||
function buildCompatMap(rows: CompatModelRow[]): CompatModelMap {
|
||||
const m = new Map<string, CompatModelRow>();
|
||||
for (const r of rows) if (r.id) m.set(r.id, r);
|
||||
return m;
|
||||
}
|
||||
|
||||
// 在组件内
|
||||
const customMap = useMemo(() => buildCompatMap(modelMeta.customModels), [modelMeta.customModels]);
|
||||
const overrideMap = useMemo(
|
||||
() => buildCompatMap(modelMeta.modelCompatOverrides),
|
||||
[modelMeta.modelCompatOverrides]
|
||||
);
|
||||
```
|
||||
|
||||
所有查找函数签名从 `(modelId, protocol, customModels[], overrides[])` 改为 `(modelId, protocol, customMap, overrideMap)`,内部使用 `Map.get()` 替代 `Array.find()`。
|
||||
|
||||
**优点**:
|
||||
|
||||
- 查找从 O(n) 降为 O(1)。
|
||||
- `useMemo` 依赖项正确,仅在数据变化时重建 Map。
|
||||
- `CustomModelsSection` 内部也独立构建 Map,不依赖父组件。
|
||||
|
||||
### 修复 7:ModelCompatPatch 类型修正(models.ts)
|
||||
|
||||
```typescript
|
||||
// 修复后 — 显式允许 null
|
||||
export type ModelCompatPatch = {
|
||||
normalizeToolCallId?: boolean;
|
||||
preserveOpenAIDeveloperRole?: boolean | null; // null = 取消设置/恢复默认
|
||||
compatByProtocol?: CompatByProtocolMap;
|
||||
};
|
||||
```
|
||||
|
||||
与 `mergeModelCompatOverride()` 内的 `=== null` 判断逻辑一致,类型安全。
|
||||
|
||||
### 修复 8:CompatByProtocolMap 类型收紧(page.tsx)
|
||||
|
||||
客户端 `CompatByProtocolMap` 从 `Record<string, ...>` 改为 `Record<ModelCompatProtocolKey, ...>`,增强类型安全,防止传入未知协议键。
|
||||
|
||||
### 修复 9:i18n 文案新增
|
||||
|
||||
| 键名 | 中文 | 英文 |
|
||||
| ------------------------------- | --------------------------------------------- | -------------------------------------------------------------- |
|
||||
| `compatProtocolLabel` | 客户端请求协议 | Client request protocol |
|
||||
| `compatProtocolHint` | 以下选项在 OmniRoute 识别到该请求形态时生效。 | These options apply when OmniRoute detects this request shape. |
|
||||
| `compatProtocolOpenAI` | OpenAI Chat Completions | OpenAI Chat Completions |
|
||||
| `compatProtocolOpenAIResponses` | OpenAI Responses API | OpenAI Responses API |
|
||||
| `compatProtocolClaude` | Anthropic Messages | Anthropic Messages |
|
||||
|
||||
---
|
||||
|
||||
## 四、使用方式
|
||||
|
||||
1. 点击模型行的 **「兼容性」** 按钮。
|
||||
2. 在弹层内先选择 **「客户端请求协议」**(OpenAI Chat / OpenAI Responses / Anthropic Messages)。
|
||||
3. 勾选该协议下的「工具 ID 9 位」或「不保留 developer 角色」。
|
||||
4. 保存后,仅在该协议形态的请求下生效。
|
||||
5. 未配置某协议时,该协议下行为回退到顶层兼容字段(若存在),再回退到默认值(保留 developer、不规范化 tool id)。
|
||||
6. 角标「ID×9」「不保留」在任意协议存在对应配置时显示。
|
||||
|
||||
---
|
||||
|
||||
## 五、预期效果
|
||||
|
||||
| 指标 | 修复前 | 修复后 |
|
||||
| ------------------------- | --------------------- | ------------------------------------------ |
|
||||
| 兼容性配置维度 | 全局(模型级) | 按协议(OpenAI Chat / Responses / Claude) |
|
||||
| developer 角色精确控制 | 不支持 | 支持(如:仅 Responses API 不保留) |
|
||||
| 前端兼容性查找性能 | O(n) Array.find | O(1) Map.get(useMemo 缓存) |
|
||||
| ModelCompatPatch 类型安全 | null 值无类型覆盖 | 显式 `boolean \| null` |
|
||||
| 客户端构建风险 | 可能引入 Node.js 模块 | 已隔离(shared/constants 层) |
|
||||
| API 验证 | 无 compatByProtocol | Zod strict schema 校验 |
|
||||
| 深色模式 | 协议选择器不可读 | bg/text 适配 dark 主题 |
|
||||
|
||||
---
|
||||
|
||||
## 六、涉及文件清单
|
||||
|
||||
| 区域 | 文件 | 改动类型 |
|
||||
| ---------- | ----------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| 协议常量 | `src/shared/constants/modelCompat.ts` | **新建**,客户端安全的协议键与类型 |
|
||||
| 存储与读写 | `src/lib/db/models.ts` | `compatByProtocol` 数据结构、深度合并、getter 第三参 `sourceFormat`、`ModelCompatPatch` 类型修正 |
|
||||
| 再导出层 | `src/lib/localDb.ts` | 新增 `ModelCompatPatch` 类型导出 |
|
||||
| API 路由 | `src/app/api/provider-models/route.ts` | PUT 支持 `compatByProtocol`,使用 `ModelCompatPatch` 类型 |
|
||||
| 输入校验 | `src/shared/validation/schemas.ts` | `modelCompatPerProtocolSchema`(strict)+ `compatByProtocol` 记录校验 |
|
||||
| 请求管线 | `open-sse/handlers/chatCore.ts` | `getModelNormalizeToolCallId` / `getModelPreserveOpenAIDeveloperRole` 传入 `sourceFormat` |
|
||||
| 前端 UI | `src/app/(dashboard)/dashboard/providers/[id]/page.tsx` | 协议选择器、按协议解析/保存、角标逻辑、Map 性能优化、类型收紧 |
|
||||
| i18n | `src/i18n/messages/en.json`,`src/i18n/messages/zh-CN.json` | 5 条新文案 |
|
||||
|
||||
---
|
||||
|
||||
## 七、回退方案
|
||||
|
||||
- **禁用按协议配置**:删除 `compatByProtocol` 字段后,getter 自动回退到顶层字段,行为与 V2 一致。
|
||||
- **前端 Map 优化回退**:将 `Map.get()` 改回 `Array.find()` 即可,纯性能优化无功能耦合。
|
||||
- **客户端常量回退**:将 `MODEL_COMPAT_PROTOCOL_KEYS` 定义移回 `models.ts` 并从 `localDb.ts` 导出(需同时确保 `node:crypto` 问题不再存在)。
|
||||
- **生产环境**:以上修复对生产构建无负面影响。`compatByProtocol` 为可选字段,未配置时默认行为不变。API Zod 校验确保不会接受畸形数据。
|
||||
@@ -17,6 +17,7 @@ import { existsSync, readFileSync } from "node:fs";
|
||||
import { join, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { homedir, platform } from "node:os";
|
||||
import { isNativeBinaryCompatible } from "../scripts/native-binary-compat.mjs";
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
@@ -193,6 +194,29 @@ if (!existsSync(serverJs)) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// ── Pre-flight: verify better-sqlite3 native binary ───────
|
||||
// Verify the binary's actual target platform/arch before trusting dlopen.
|
||||
// This avoids the macOS false positive where a bundled linux-x64 addon can
|
||||
// appear to load even though the runtime will fail when better-sqlite3 starts.
|
||||
const sqliteBinary = join(
|
||||
APP_DIR,
|
||||
"node_modules",
|
||||
"better-sqlite3",
|
||||
"build",
|
||||
"Release",
|
||||
"better_sqlite3.node"
|
||||
);
|
||||
if (existsSync(sqliteBinary) && !isNativeBinaryCompatible(sqliteBinary)) {
|
||||
console.error(
|
||||
"\x1b[31m✖ better-sqlite3 native module is incompatible with this platform.\x1b[0m"
|
||||
);
|
||||
console.error(` Run: cd ${APP_DIR} && npm rebuild better-sqlite3`);
|
||||
if (platform() === "darwin") {
|
||||
console.error(" If build tools are missing: xcode-select --install");
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// ── Start server ───────────────────────────────────────────
|
||||
console.log(` \x1b[2m⏳ Starting server...\x1b[0m\n`);
|
||||
|
||||
|
||||
196
docs/A2A-SERVER.md
Normal file
196
docs/A2A-SERVER.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# OmniRoute A2A Server Documentation
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
|
||||
## Agent Discovery
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
|
||||
---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a hello world in Python"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `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 '{
|
||||
"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":"..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"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"}}'
|
||||
```
|
||||
|
||||
### `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"}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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. |
|
||||
|
||||
---
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
---
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
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"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
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",
|
||||
},
|
||||
body: 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);
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
# API Reference
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md) | 🇨🇿 [Čeština](i18n/cs/API_REFERENCE.md)
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
@@ -260,6 +260,16 @@ Response example:
|
||||
|
||||
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 |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OmniRoute Architecture
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](i18n/cs/ARCHITECTURE.md)
|
||||
|
||||
_Last updated: 2026-03-04_
|
||||
|
||||
|
||||
63
docs/AUTO-COMBO.md
Normal file
63
docs/AUTO-COMBO.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# OmniRoute Auto-Combo Engine
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
|
||||
## How It Works
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
|
||||
| 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 |
|
||||
|
||||
## Mode Packs
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
curl -X POST http://localhost:20128/api/combos/auto \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
|
||||
|
||||
# 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).
|
||||
|
||||
## 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 |
|
||||
347
docs/CLI-TOOLS.md
Normal file
347
docs/CLI-TOOLS.md
Normal file
@@ -0,0 +1,347 @@
|
||||
# CLI Tools Setup Guide — OmniRoute
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
|
||||
│
|
||||
▼ (all point to OmniRoute)
|
||||
http://YOUR_SERVER:20128/v1
|
||||
│
|
||||
▼ (OmniRoute routes to the right provider)
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## Supported Tools
|
||||
|
||||
| Tool | Command | Type | Install Method |
|
||||
| ---------------- | ------------------- | ----------------- | -------------- |
|
||||
| **Claude Code** | `claude` | CLI | npm |
|
||||
| **OpenAI Codex** | `codex` | CLI | npm |
|
||||
| **Gemini CLI** | `gemini` | CLI | npm |
|
||||
| **OpenCode** | `opencode` | CLI | npm |
|
||||
| **Cline** | `cline` | CLI + VS Code ext | npm |
|
||||
| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code ext | npm |
|
||||
| **Continue** | guide-based | VS Code ext | VS Code |
|
||||
| **Kiro CLI** | `kiro-cli` | CLI | curl installer |
|
||||
| **Cursor** | `cursor` | Desktop app | Download |
|
||||
| **Droid** | web-based | Built-in agent | OmniRoute |
|
||||
| **OpenClaw** | web-based | Built-in agent | OmniRoute |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
npm install -g @openai/codex
|
||||
|
||||
# Gemini CLI (Google)
|
||||
npm install -g @google/gemini-cli
|
||||
|
||||
# OpenCode
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
npm install -g kilecode
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
|
||||
```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
gemini --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`:
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
# Via CLI:
|
||||
claude config set --global api-base-url http://localhost:20128/v1
|
||||
|
||||
# Or create ~/.claude/settings.json:
|
||||
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
{
|
||||
"apiBaseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
|
||||
### Gemini CLI
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
|
||||
{
|
||||
"apiKey": "sk-your-omniroute-key",
|
||||
"baseUrl": "http://localhost:20128/v1"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `gemini "hello"`
|
||||
|
||||
---
|
||||
|
||||
### OpenCode
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"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**.
|
||||
|
||||
---
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
|
||||
---
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
model: auto
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
```bash
|
||||
# Login to your AWS/Kiro account:
|
||||
kiro-cli login
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | 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 |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| 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"` |
|
||||
|
||||
---
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
```bash
|
||||
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
|
||||
OMNIROUTE_URL="http://localhost:20128/v1"
|
||||
OMNIROUTE_KEY="sk-your-omniroute-key"
|
||||
|
||||
npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode
|
||||
|
||||
# Kiro CLI
|
||||
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
|
||||
|
||||
# Write configs
|
||||
mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue
|
||||
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}"
|
||||
cat >> ~/.bashrc << EOF
|
||||
export OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
export OPENAI_API_KEY="$OMNIROUTE_KEY"
|
||||
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
|
||||
EOF
|
||||
|
||||
source ~/.bashrc
|
||||
echo "✅ All CLIs installed and configured for OmniRoute"
|
||||
```
|
||||
@@ -1,6 +1,6 @@
|
||||
# omniroute — Codebase Documentation
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md) | 🇨🇿 [Čeština](i18n/cs/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# OmniRoute — Dashboard Features Gallery
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](FEATURES.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/FEATURES.md) | 🇪🇸 [Español](i18n/es/FEATURES.md) | 🇫🇷 [Français](i18n/fr/FEATURES.md) | 🇮🇹 [Italiano](i18n/it/FEATURES.md) | 🇷🇺 [Русский](i18n/ru/FEATURES.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](i18n/de/FEATURES.md) | 🇮🇳 [हिन्दी](i18n/in/FEATURES.md) | 🇹🇭 [ไทย](i18n/th/FEATURES.md) | 🇺🇦 [Українська](i18n/uk-UA/FEATURES.md) | 🇸🇦 [العربية](i18n/ar/FEATURES.md) | 🇯🇵 [日本語](i18n/ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](i18n/vi/FEATURES.md) | 🇧🇬 [Български](i18n/bg/FEATURES.md) | 🇩🇰 [Dansk](i18n/da/FEATURES.md) | 🇫🇮 [Suomi](i18n/fi/FEATURES.md) | 🇮🇱 [עברית](i18n/he/FEATURES.md) | 🇭🇺 [Magyar](i18n/hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/FEATURES.md) | 🇰🇷 [한국어](i18n/ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/FEATURES.md) | 🇳🇱 [Nederlands](i18n/nl/FEATURES.md) | 🇳🇴 [Norsk](i18n/no/FEATURES.md) | 🇵🇹 [Português (Portugal)](i18n/pt/FEATURES.md) | 🇷🇴 [Română](i18n/ro/FEATURES.md) | 🇵🇱 [Polski](i18n/pl/FEATURES.md) | 🇸🇰 [Slovenčina](i18n/sk/FEATURES.md) | 🇸🇪 [Svenska](i18n/sv/FEATURES.md) | 🇵🇭 [Filipino](i18n/phi/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](FEATURES.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/FEATURES.md) | 🇪🇸 [Español](i18n/es/FEATURES.md) | 🇫🇷 [Français](i18n/fr/FEATURES.md) | 🇮🇹 [Italiano](i18n/it/FEATURES.md) | 🇷🇺 [Русский](i18n/ru/FEATURES.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](i18n/de/FEATURES.md) | 🇮🇳 [हिन्दी](i18n/in/FEATURES.md) | 🇹🇭 [ไทย](i18n/th/FEATURES.md) | 🇺🇦 [Українська](i18n/uk-UA/FEATURES.md) | 🇸🇦 [العربية](i18n/ar/FEATURES.md) | 🇯🇵 [日本語](i18n/ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](i18n/vi/FEATURES.md) | 🇧🇬 [Български](i18n/bg/FEATURES.md) | 🇩🇰 [Dansk](i18n/da/FEATURES.md) | 🇫🇮 [Suomi](i18n/fi/FEATURES.md) | 🇮🇱 [עברית](i18n/he/FEATURES.md) | 🇭🇺 [Magyar](i18n/hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/FEATURES.md) | 🇰🇷 [한국어](i18n/ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/FEATURES.md) | 🇳🇱 [Nederlands](i18n/nl/FEATURES.md) | 🇳🇴 [Norsk](i18n/no/FEATURES.md) | 🇵🇹 [Português (Portugal)](i18n/pt/FEATURES.md) | 🇷🇴 [Română](i18n/ro/FEATURES.md) | 🇵🇱 [Polski](i18n/pl/FEATURES.md) | 🇸🇰 [Slovenčina](i18n/sk/FEATURES.md) | 🇸🇪 [Svenska](i18n/sv/FEATURES.md) | 🇵🇭 [Filipino](i18n/phi/FEATURES.md) | 🇨🇿 [Čeština](i18n/cs/FEATURES.md)
|
||||
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
@@ -8,7 +8,7 @@ Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (iFlow, Qwen, Kiro).
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (iFlow, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

|
||||
|
||||
@@ -16,7 +16,7 @@ Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI)
|
||||
|
||||
## 🎨 Combos
|
||||
|
||||
Create model routing combos with 6 strategies: fill-first, round-robin, power-of-two-choices, random, least-used, and cost-optimized. Each combo chains multiple models with automatic fallback.
|
||||
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.
|
||||
|
||||

|
||||
|
||||
@@ -46,9 +46,28 @@ Four modes for debugging API translations: **Playground** (format converter), **
|
||||
|
||||
---
|
||||
|
||||
## 🎮 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+)_
|
||||
|
||||
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
|
||||
|
||||
General settings, system storage, backup management (export/import database), appearance (dark/light mode), security (includes API endpoint protection and custom provider blocking), routing (model aliases, background task degradation), resilience (rate limit persistence), and advanced configuration.
|
||||
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
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning
|
||||
- **Advanced** — Configuration overrides
|
||||
|
||||

|
||||
|
||||
@@ -56,12 +75,29 @@ General settings, system storage, backup management (export/import database), ap
|
||||
|
||||
## 🔧 CLI Tools
|
||||
|
||||
One-click configuration for AI coding tools: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, and **GitHub Copilot** (config generator for `chatLanguageModels.json`).
|
||||
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.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🤖 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:
|
||||
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ 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.
|
||||
@@ -72,15 +108,27 @@ Real-time request logging with filtering by provider, model, account, and API ke
|
||||
|
||||
## 🌐 API Endpoint
|
||||
|
||||
Your unified API endpoint with capability breakdown: Chat Completions, Embeddings, Image Generation, Reranking, Audio Transcription, and registered API keys.
|
||||
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. Cloud proxy support for remote access.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔑 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.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Audit Log
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop Application
|
||||
|
||||
Native Electron desktop app for Windows, macOS, and Linux. Run OmniRoute as a standalone application with system tray integration, offline support, and one-click install.
|
||||
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:
|
||||
|
||||
@@ -88,6 +136,8 @@ Key features:
|
||||
- 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.
|
||||
|
||||
83
docs/MCP-SERVER.md
Normal file
83
docs/MCP-SERVER.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# OmniRoute MCP Server Documentation
|
||||
|
||||
> Model Context Protocol server with 16 intelligent tools
|
||||
|
||||
## Installation
|
||||
|
||||
OmniRoute MCP is built-in. Start it with:
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Or via the open-sse transport:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
```
|
||||
|
||||
## IDE Configuration
|
||||
|
||||
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
## 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 |
|
||||
| `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 |
|
||||
|
||||
## Authentication
|
||||
|
||||
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 |
|
||||
|
||||
## 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 |
|
||||
113
docs/TASKS.md
113
docs/TASKS.md
@@ -1,113 +0,0 @@
|
||||
# Rate Limiting & Flow Control Overhaul — Tasks
|
||||
|
||||
> Referência: [Relatório de Análise](../walkthrough.md) · Fase docs em `/docs/phases/`
|
||||
|
||||
---
|
||||
|
||||
## Fase 1 — Error Classification & Provider Profiles
|
||||
|
||||
### Backend Core
|
||||
|
||||
- [x] `constants.ts` — Substituir `COOLDOWN_MS.transient` por `transientInitial` (5s) + `transientMax` (60s)
|
||||
- [x] `constants.ts` — Adicionar `PROVIDER_PROFILES` (oauth / apikey) com cooldowns diferenciados
|
||||
- [x] `constants.ts` — Adicionar `DEFAULT_API_LIMITS` (100 RPM, 200ms minTime)
|
||||
- [x] `providerRegistry.ts` — Criar helper `getProviderCategory(providerId)` → `"oauth"` | `"apikey"`
|
||||
- [x] `accountFallback.ts` — Aceitar `provider` como parâmetro em `checkFallbackError`
|
||||
- [x] `accountFallback.ts` — Implementar backoff exponencial para 502/503/504 transientes
|
||||
- [x] `accountFallback.ts` — Calcular cooldown baseado no perfil do provedor
|
||||
- [x] `accountFallback.ts` — Adicionar helper `getProviderProfile(provider)`
|
||||
|
||||
### Callers (propagar `provider`)
|
||||
|
||||
- [x] `auth.ts` → `markAccountUnavailable` — Passar `provider` para `checkFallbackError`
|
||||
- [x] `combo.ts` → `handleComboChat` / `handleRoundRobinCombo` — Passar `provider` nos erros
|
||||
|
||||
### Testes
|
||||
|
||||
- [x] Atualizar `rate-limit-enhanced.test.mjs` — Teste "transient errors don't increase backoff" → `newBackoffLevel = 1`
|
||||
- [x] Criar `error-classification.test.mjs` — Cooldown exponencial 502, perfis OAuth/API, helper `getProviderCategory`
|
||||
|
||||
---
|
||||
|
||||
## Fase 2 — Circuit Breaker no Combo Pipeline
|
||||
|
||||
### Backend
|
||||
|
||||
- [x] `combo.ts` — Importar `getCircuitBreaker` e `CircuitBreakerOpenError`
|
||||
- [x] `combo.ts` — `handleComboChat` — Verificar `breaker.canExecute()` antes de cada modelo
|
||||
- [x] `combo.ts` — `handleRoundRobinCombo` — Integrar breaker per-model
|
||||
- [x] `combo.ts` — Marcar `semaphore.markRateLimited` para 502/503/504 (não só 429)
|
||||
- [x] `combo.ts` — Implementar early exit quando todos os modelos têm breaker OPEN
|
||||
|
||||
### Testes
|
||||
|
||||
- [x] Criar `combo-circuit-breaker.test.mjs` — Combo skip breaker OPEN, early exit, semáforo 502
|
||||
|
||||
---
|
||||
|
||||
## Fase 3 — Anti-Thundering Herd & Auto Rate Limit
|
||||
|
||||
### Backend
|
||||
|
||||
- [x] `rateLimitManager.ts` — Auto-enable para `apikey` providers com limites elevados
|
||||
- [x] `rateLimitManager.ts` — Criar limiter com defaults (100 RPM) quando não configurado
|
||||
- [x] `auth.ts` — Adicionar mutex na `markAccountUnavailable` para evitar marcação paralela
|
||||
|
||||
### Testes
|
||||
|
||||
- [x] Criar `thundering-herd.test.mjs` — Mutex, auto-enable, limites não restritivos
|
||||
|
||||
---
|
||||
|
||||
## Fase 4 — Frontend Resilience UI
|
||||
|
||||
### Settings Page
|
||||
|
||||
- [x] `settings/page.tsx` — Adicionar tab "Resilience" (icon: `health_and_safety`) entre Routing e Pricing
|
||||
|
||||
### Novos Componentes
|
||||
|
||||
- [x] Criar `ResilienceTab.tsx` — Layout com 4 cards (Provider Profiles → Rate Limiting → Circuit Breakers → Policies)
|
||||
- [x] Criar `ProviderProfilesCard.tsx` — Toggle OAuth/API Key, inputs para cooldowns
|
||||
- [x] Criar `CircuitBreakerCard.tsx` — Status real-time per-provider, auto-refresh 5s, botão reset
|
||||
- [x] Criar `RateLimitOverviewCard.tsx` — Tabela providers × accounts × cooldown — **agora editável com RPM, Min Gap, Max Concurrent**
|
||||
|
||||
### API Routes
|
||||
|
||||
- [x] Criar `api/resilience/route.ts` — GET (estado completo + defaults mesclados) + PATCH (salvar perfis + defaults)
|
||||
- [x] Criar `api/resilience/reset/route.ts` — POST (resetar breakers + cooldowns)
|
||||
|
||||
### Migração
|
||||
|
||||
- [x] `PoliciesPanel.tsx` movido de Security para Resilience tab
|
||||
|
||||
---
|
||||
|
||||
## Fase 5 — Settings Page Restructure (v0.9.0)
|
||||
|
||||
### Tab Reorganization
|
||||
|
||||
- [x] **Security** — Simplificado para Login/Password + IP Access Control
|
||||
- [x] **Routing** — Expandido para 6 estratégias globais com descrições
|
||||
- [x] **Resilience** — Reordenado: Provider Profiles → Rate Limiting (editável) → Circuit Breakers → Policies
|
||||
- [x] **AI** — Thinking Budget + System Prompt + Prompt Cache (movido do Advanced)
|
||||
- [x] **Advanced** — Simplificado para apenas Global Proxy
|
||||
|
||||
### Backend Routing Strategies
|
||||
|
||||
- [x] `auth.ts` — Implementar `random` (Fisher-Yates shuffle)
|
||||
- [x] `auth.ts` — Implementar `least-used` (sorted by lastUsedAt)
|
||||
- [x] `auth.ts` — Implementar `cost-optimized` (sorted by priority)
|
||||
- [x] `auth.ts` — Corrigir `p2c` (power-of-two-choices com health scoring)
|
||||
- [x] `settings.ts` — Expandir tipo `fallbackStrategy` para 6 valores
|
||||
|
||||
---
|
||||
|
||||
## Verificação Final
|
||||
|
||||
- [x] Rodar todos os testes unitários: `node --test tests/unit/*.test.mjs`
|
||||
- [x] Build do Next.js: `npm run build`
|
||||
- [x] Verificar aba Resilience no browser
|
||||
- [x] Testar persistência dos perfis (salvar → reload)
|
||||
- [x] Testar Reset All Breakers
|
||||
- [x] Verificar todas as 5 tabs reestruturadas
|
||||
@@ -1,6 +1,6 @@
|
||||
# Troubleshooting
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md) | 🇨🇿 [Čeština](i18n/cs/TROUBLESHOOTING.md)
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# User Guide
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](i18n/es/USER_GUIDE.md) | 🇫🇷 [Français](i18n/fr/USER_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/USER_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/USER_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/USER_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/USER_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/USER_GUIDE.md) | 🇧🇬 [Български](i18n/bg/USER_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/USER_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/USER_GUIDE.md) | 🇮🇱 [עברית](i18n/he/USER_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/USER_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/USER_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/USER_GUIDE.md) | 🇷🇴 [Română](i18n/ro/USER_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/USER_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/USER_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/USER_GUIDE.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](i18n/es/USER_GUIDE.md) | 🇫🇷 [Français](i18n/fr/USER_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/USER_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/USER_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/USER_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/USER_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/USER_GUIDE.md) | 🇧🇬 [Български](i18n/bg/USER_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/USER_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/USER_GUIDE.md) | 🇮🇱 [עברית](i18n/he/USER_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/USER_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/USER_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/USER_GUIDE.md) | 🇷🇴 [Română](i18n/ro/USER_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/USER_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/USER_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/USER_GUIDE.md) | 🇨🇿 [Čeština](i18n/cs/USER_GUIDE.md)
|
||||
|
||||
Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
|
||||
|
||||
|
||||
@@ -1,69 +1,71 @@
|
||||
# OmniRoute — Guia de Deploy em VM com Cloudflare
|
||||
# OmniRoute — Deployment Guide on VM with Cloudflare
|
||||
|
||||
Guia completo para instalar e configurar o OmniRoute em uma VM (VPS) com domínio gerenciado via Cloudflare.
|
||||
🌐 **Languages:** 🇺🇸 [English](VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](i18n/es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](i18n/fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](i18n/bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](i18n/he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](i18n/ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](i18n/cs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
Complete guide to install and configure OmniRoute on a VM (VPS) with domain managed via Cloudflare.
|
||||
|
||||
---
|
||||
|
||||
## Pré-Requisitos
|
||||
## Prerequisites
|
||||
|
||||
| Item | Mínimo | Recomendado |
|
||||
| ----------- | ------------------------ | ---------------- |
|
||||
| **CPU** | 1 vCPU | 2 vCPU |
|
||||
| **RAM** | 1 GB | 2 GB |
|
||||
| **Disco** | 10 GB SSD | 25 GB SSD |
|
||||
| **SO** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|
||||
| **Domínio** | Registrado no Cloudflare | — |
|
||||
| **Docker** | Docker Engine 24+ | Docker 27+ |
|
||||
| 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+ |
|
||||
|
||||
**Providers testados**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
|
||||
**Tested providers**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
|
||||
|
||||
---
|
||||
|
||||
## 1. Configurar a VM
|
||||
## 1. Configure the VM
|
||||
|
||||
### 1.1 Criar a instância
|
||||
### 1.1 Create the instance
|
||||
|
||||
No seu provider de VPS preferido:
|
||||
On your preferred VPS provider:
|
||||
|
||||
- Escolha Ubuntu 24.04 LTS
|
||||
- Selecione o plano mínimo (1 vCPU / 1 GB RAM)
|
||||
- Defina uma senha forte para root ou configure SSH key
|
||||
- Anote o **IP público** (ex: `203.0.113.10`)
|
||||
- Choose Ubuntu 24.04 LTS
|
||||
- Select the minimum plan (1 vCPU / 1 GB RAM)
|
||||
- Set a strong root password or configure SSH key
|
||||
- Note the **public IP** (e.g., `203.0.113.10`)
|
||||
|
||||
### 1.2 Conectar via SSH
|
||||
### 1.2 Connect via SSH
|
||||
|
||||
```bash
|
||||
ssh root@203.0.113.10
|
||||
```
|
||||
|
||||
### 1.3 Atualizar o sistema
|
||||
### 1.3 Update the system
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
|
||||
### 1.4 Instalar Docker
|
||||
### 1.4 Install Docker
|
||||
|
||||
```bash
|
||||
# Instalar dependências
|
||||
# Install dependencies
|
||||
apt install -y ca-certificates curl gnupg
|
||||
|
||||
# Adicionar repositório oficial do Docker
|
||||
# Add official Docker repository
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $ (. /etc/os-release && echo “$VERSION_CODENAME”) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt update
|
||||
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
|
||||
### 1.5 Instalar nginx
|
||||
### 1.5 Install nginx
|
||||
|
||||
```bash
|
||||
apt install -y nginx
|
||||
```
|
||||
|
||||
### 1.6 Configurar Firewall (UFW)
|
||||
### 1.6 Configure Firewall (UFW)
|
||||
|
||||
```bash
|
||||
ufw default deny incoming
|
||||
@@ -74,29 +76,29 @@ ufw allow 443/tcp # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
> **Dica**: Para segurança máxima, restrinja as portas 80 e 443 apenas para IPs da Cloudflare. Veja a seção [Segurança Avançada](#segurança-avançada).
|
||||
> **Tip**: For maximum security, restrict ports 80 and 443 to Cloudflare IPs only. See the [Advanced Security](#advanced-security) section.
|
||||
|
||||
---
|
||||
|
||||
## 2. Instalar o OmniRoute
|
||||
## 2. Install OmniRoute
|
||||
|
||||
### 2.1 Criar diretório de configuração
|
||||
### 2.1 Create configuration directory
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/omniroute
|
||||
```
|
||||
|
||||
### 2.2 Criar arquivo de variáveis de ambiente
|
||||
### 2.2 Create environment variables file
|
||||
|
||||
```bash
|
||||
cat > /opt/omniroute/.env << 'EOF'
|
||||
# === Segurança ===
|
||||
JWT_SECRET=ALTERE-PARA-CHAVE-SECRETA-UNICA-64-CHARS
|
||||
INITIAL_PASSWORD=SuaSenhaSegura123!
|
||||
API_KEY_SECRET=ALTERE-PARA-OUTRA-CHAVE-SECRETA
|
||||
STORAGE_ENCRYPTION_KEY=ALTERE-PARA-TERCEIRA-CHAVE-SECRETA
|
||||
cat > /opt/omniroute/.env << ‘EOF’
|
||||
# === Security ===
|
||||
JWT_SECRET=CHANGE-TO-A-UNIQUE-64-CHAR-SECRET-KEY
|
||||
INITIAL_PASSWORD=YourSecurePassword123!
|
||||
API_KEY_SECRET=REPLACE-WITH-ANOTHER-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY=REPLACE-WITH-THIRD-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY_VERSION=v1
|
||||
MACHINE_ID_SALT=ALTERE-PARA-SALT-UNICO
|
||||
MACHINE_ID_SALT=CHANGE-TO-A-UNIQUE-SALT
|
||||
|
||||
# === App ===
|
||||
PORT=20128
|
||||
@@ -108,19 +110,19 @@ ENABLE_REQUEST_LOGS=true
|
||||
AUTH_COOKIE_SECURE=false
|
||||
REQUIRE_API_KEY=false
|
||||
|
||||
# === Domain (altere para seu domínio) ===
|
||||
# === Domain (change to your domain) ===
|
||||
BASE_URL=https://llms.seudominio.com
|
||||
NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
|
||||
|
||||
# === Cloud Sync (opcional) ===
|
||||
# === Cloud Sync (optional) ===
|
||||
# CLOUD_URL=https://cloud.omniroute.online
|
||||
# NEXT_PUBLIC_CLOUD_URL=https://cloud.omniroute.online
|
||||
EOF
|
||||
```
|
||||
|
||||
> ⚠️ **IMPORTANTE**: Gere chaves secretas únicas! Use `openssl rand -hex 32` para cada chave.
|
||||
> ⚠️ **IMPORTANT**: Generate unique secret keys! Use `openssl rand -hex 32` for each key.
|
||||
|
||||
### 2.3 Iniciar o container
|
||||
### 2.3 Start the container
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
@@ -134,45 +136,45 @@ docker run -d \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
|
||||
### 2.4 Verificar se está rodando
|
||||
### 2.4 Verify that it is running
|
||||
|
||||
```bash
|
||||
docker ps | grep omniroute
|
||||
docker logs omniroute --tail 20
|
||||
```
|
||||
|
||||
Deve exibir: `[DB] SQLite database ready` e `listening on port 20128`.
|
||||
It should display: `[DB] SQLite database ready` and `listening on port 20128`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Configurar nginx (Reverse Proxy)
|
||||
## 3. Configure nginx (Reverse Proxy)
|
||||
|
||||
### 3.1 Gerar certificado SSL (Cloudflare Origin)
|
||||
### 3.1 Generate SSL certificate (Cloudflare Origin)
|
||||
|
||||
No painel da Cloudflare:
|
||||
In the Cloudflare dashboard:
|
||||
|
||||
1. Vá em **SSL/TLS → Origin Server**
|
||||
2. Clique **Create Certificate**
|
||||
3. Deixe os padrões (15 anos, \*.seudominio.com)
|
||||
4. Copie o **Origin Certificate** e a **Private Key**
|
||||
1. Go to **SSL/TLS → Origin Server**
|
||||
2. Click **Create Certificate**
|
||||
3. Keep the defaults (15 years, \*.yourdomain.com)
|
||||
4. Copy the **Origin Certificate** and the **Private Key**
|
||||
|
||||
```bash
|
||||
mkdir -p /etc/nginx/ssl
|
||||
|
||||
# Colar o certificado
|
||||
# Paste the certificate
|
||||
nano /etc/nginx/ssl/origin.crt
|
||||
|
||||
# Colar a chave privada
|
||||
# Paste the private key
|
||||
nano /etc/nginx/ssl/origin.key
|
||||
|
||||
chmod 600 /etc/nginx/ssl/origin.key
|
||||
```
|
||||
|
||||
### 3.2 Configuração do nginx
|
||||
### 3.2 Nginx Configuration
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/omniroute << 'NGINX'
|
||||
# Default server — bloqueia acesso direto por IP
|
||||
cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
|
||||
# Default server — blocks direct access via IP
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
@@ -188,7 +190,7 @@ server {
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name llms.seudominio.com; # Altere para seu domínio
|
||||
server_name llms.yourdomain.com; # Change to your domain
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
@@ -206,7 +208,7 @@ server {
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Connection “upgrade”;
|
||||
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
@@ -220,61 +222,61 @@ server {
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name llms.seudominio.com;
|
||||
server_name llms.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
NGINX
|
||||
```
|
||||
|
||||
### 3.3 Ativar e testar
|
||||
### 3.3 Enable and Test
|
||||
|
||||
```bash
|
||||
# Remover config padrão
|
||||
# Remove default configuration
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Ativar OmniRoute
|
||||
# Enable OmniRoute
|
||||
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
|
||||
|
||||
# Testar e recarregar
|
||||
# Test and reload
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Configurar Cloudflare DNS
|
||||
## 4. Configure Cloudflare DNS
|
||||
|
||||
### 4.1 Adicionar registro DNS
|
||||
### 4.1 Add DNS record
|
||||
|
||||
No painel da Cloudflare → DNS:
|
||||
In the Cloudflare dashboard → DNS:
|
||||
|
||||
| Type | Name | Content | Proxy |
|
||||
| ---- | ------ | ------------------------- | ---------- |
|
||||
| A | `llms` | `203.0.113.10` (IP da VM) | ✅ Proxied |
|
||||
| Type | Name | Content | Proxy |
|
||||
| ---- | ------ | ---------------------- | ---------- |
|
||||
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Proxied |
|
||||
|
||||
### 4.2 Configurar SSL
|
||||
### 4.2 Configure SSL
|
||||
|
||||
Em **SSL/TLS → Overview**:
|
||||
Under **SSL/TLS → Overview**:
|
||||
|
||||
- Modo: **Full (Strict)**
|
||||
- Mode: **Full (Strict)**
|
||||
|
||||
Em **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 Testar
|
||||
### 4.3 Testing
|
||||
|
||||
```bash
|
||||
curl -sI https://llms.seudominio.com/health
|
||||
# Deve retornar HTTP/2 200
|
||||
# Should return HTTP/2 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Operações e Manutenção
|
||||
## 5. Operations and Maintenance
|
||||
|
||||
### Atualizar para nova versão
|
||||
### Upgrade to a new version
|
||||
|
||||
```bash
|
||||
docker pull diegosouzapw/omniroute:latest
|
||||
@@ -286,42 +288,42 @@ docker run -d --name omniroute --restart unless-stopped \
|
||||
diegosouzapw/omniroute:latest
|
||||
```
|
||||
|
||||
### Ver logs
|
||||
### View logs
|
||||
|
||||
```bash
|
||||
docker logs -f omniroute # Stream em tempo real
|
||||
docker logs omniroute --tail 50 # Últimas 50 linhas
|
||||
docker logs -f omniroute # Real-time stream
|
||||
docker logs omniroute --tail 50 # Last 50 lines
|
||||
```
|
||||
|
||||
### Backup manual do banco
|
||||
### Manual database backup
|
||||
|
||||
```bash
|
||||
# Copiar dados do volume para o host
|
||||
# Copy data from the volume to the host
|
||||
docker cp omniroute:/app/data ./backup-$(date +%F)
|
||||
|
||||
# Ou comprimir todo o volume
|
||||
# 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
|
||||
```
|
||||
|
||||
### Restaurar de backup
|
||||
### 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 /"
|
||||
alpine sh -c “rm -rf /data/* && tar xzf /backup/omniroute-data-YYYY-MM-DD.tar.gz -C /”
|
||||
docker start omniroute
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Segurança Avançada
|
||||
## 6. Advanced Security
|
||||
|
||||
### Restringir nginx para Cloudflare IPs
|
||||
### Restrict nginx to Cloudflare IPs
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/cloudflare-ips.conf << 'CF'
|
||||
# Cloudflare IPv4 ranges — atualizar periodicamente
|
||||
cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
|
||||
# Cloudflare IPv4 ranges — update periodically
|
||||
# https://www.cloudflare.com/ips-v4/
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
@@ -342,7 +344,7 @@ real_ip_header CF-Connecting-IP;
|
||||
CF
|
||||
```
|
||||
|
||||
Adicionar no `nginx.conf` dentro do bloco `http {}`:
|
||||
Add the following to `nginx.conf` inside the `http {}` block:
|
||||
|
||||
```nginx
|
||||
include /etc/nginx/cloudflare-ips.conf;
|
||||
@@ -355,45 +357,45 @@ apt install -y fail2ban
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
# Verificar status
|
||||
# Check status
|
||||
fail2ban-client status sshd
|
||||
```
|
||||
|
||||
### Bloquear acesso direto na porta do Docker
|
||||
### Block direct access to the Docker port
|
||||
|
||||
```bash
|
||||
# Impedir acesso externo direto à porta 20128
|
||||
# Prevent direct external access to port 20128
|
||||
iptables -I DOCKER-USER -p tcp --dport 20128 -j DROP
|
||||
iptables -I DOCKER-USER -i lo -p tcp --dport 20128 -j ACCEPT
|
||||
|
||||
# Persistir as regras
|
||||
# Persist the rules
|
||||
apt install -y iptables-persistent
|
||||
netfilter-persistent save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Deploy do Cloud Worker (Opcional)
|
||||
## 7. Deploy to Cloudflare Workers (Optional)
|
||||
|
||||
Para acesso remoto via Cloudflare Workers (sem expor a VM diretamente):
|
||||
For remote access via Cloudflare Workers (without exposing the VM directly):
|
||||
|
||||
```bash
|
||||
# No repositório local
|
||||
# In the local repository
|
||||
cd omnirouteCloud
|
||||
npm install
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
Ver documentação completa em [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
See the full documentation at [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
|
||||
---
|
||||
|
||||
## Resumo de Portas
|
||||
## Port Summary
|
||||
|
||||
| Porta | Serviço | Acesso |
|
||||
| ----- | ----------- | ----------------------------- |
|
||||
| 22 | SSH | Público (com fail2ban) |
|
||||
| 80 | nginx HTTP | Redirect → HTTPS |
|
||||
| 443 | nginx HTTPS | Via Cloudflare Proxy |
|
||||
| 20128 | OmniRoute | Somente localhost (via nginx) |
|
||||
| Port | Service | Access |
|
||||
| ----- | ----------- | -------------------------- |
|
||||
| 22 | SSH | Public (with fail2ban) |
|
||||
| 80 | nginx HTTP | Redirect → HTTPS |
|
||||
| 443 | nginx HTTPS | Via Cloudflare Proxy |
|
||||
| 20128 | OmniRoute | Localhost only (via nginx) |
|
||||
|
||||
46
docs/adr/0001-proxy-registry-limit-generalization.md
Normal file
46
docs/adr/0001-proxy-registry-limit-generalization.md
Normal file
@@ -0,0 +1,46 @@
|
||||
# ADR-0001: Proxy Registry + Usage Control Generalization
|
||||
|
||||
Date: 2026-03-17
|
||||
Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute sudah punya:
|
||||
|
||||
- Proxy assignment berbasis config-map (`global`, `providers`, `combos`, `keys`).
|
||||
- Quota-aware selection khusus provider tertentu (notably `codex`).
|
||||
|
||||
Gap utama:
|
||||
|
||||
- Proxy belum menjadi aset reusable yang bisa di-manage sebagai entitas (metadata, where-used, safe delete).
|
||||
- Usage policy belum konsisten lintas provider.
|
||||
- Error contract API belum seragam untuk endpoint manajemen.
|
||||
|
||||
## Decision
|
||||
|
||||
1. Tambah **Proxy Registry** sebagai domain baru di DB (`proxy_registry`, `proxy_assignments`).
|
||||
2. Pertahankan kompatibilitas assignment lama (fallback ke `proxyConfig` lama).
|
||||
3. Resolver runtime pakai prioritas:
|
||||
- account -> provider -> global (registry)
|
||||
- fallback ke legacy resolver jika registry belum ada assignment
|
||||
4. Wajib redaction kredensial di output list registry default.
|
||||
5. Standarkan error JSON untuk endpoint manajemen proxy agar konsisten dan punya `requestId`.
|
||||
|
||||
## Consequences
|
||||
|
||||
Positif:
|
||||
|
||||
- Proxy reusable dan bisa dilacak pemakaiannya.
|
||||
- Safe delete bisa ditegakkan (409 saat masih dipakai).
|
||||
- Migrasi bertahap tanpa breaking change runtime.
|
||||
|
||||
Negatif:
|
||||
|
||||
- Ada dual-source sementara (registry + legacy config) sampai migrasi selesai.
|
||||
- Butuh endpoint assignment tambahan dan pemetaan scope yang konsisten.
|
||||
|
||||
## Follow-up
|
||||
|
||||
- Migrasi UI provider/account dari input raw proxy ke selector registry.
|
||||
- Tambah health telemetry per proxy dan alerting.
|
||||
- Generalisasi usage control ke provider lain melalui interface policy yang sama.
|
||||
32
docs/adr/0002-api-error-contract-management-endpoints.md
Normal file
32
docs/adr/0002-api-error-contract-management-endpoints.md
Normal file
@@ -0,0 +1,32 @@
|
||||
# ADR-0002: Error Contract for Management Endpoints
|
||||
|
||||
Date: 2026-03-17
|
||||
Status: Accepted
|
||||
|
||||
## Decision
|
||||
|
||||
Management endpoints (proxy config, proxy registry, and proxy assignments) return a uniform error body:
|
||||
|
||||
```json
|
||||
{
|
||||
"error": {
|
||||
"message": "Human-readable summary",
|
||||
"type": "invalid_request | not_found | conflict | server_error",
|
||||
"details": {}
|
||||
},
|
||||
"requestId": "uuid"
|
||||
}
|
||||
```
|
||||
|
||||
## Status Mapping
|
||||
|
||||
- 400: invalid request / validation failure
|
||||
- 404: resource not found
|
||||
- 409: resource conflict (for example, proxy still assigned)
|
||||
- 500: unexpected server error
|
||||
|
||||
## Notes
|
||||
|
||||
- `requestId` is mandatory for log correlation.
|
||||
- `details` is optional and only used for safe validation details.
|
||||
- Sensitive secrets (proxy credentials, tokens) must never appear in `message` or `details`.
|
||||
16
docs/adr/0003-security-checklist-proxy-limits.md
Normal file
16
docs/adr/0003-security-checklist-proxy-limits.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# ADR-0003: Security Checklist for Proxy Registry and Usage Controls
|
||||
|
||||
Date: 2026-03-17
|
||||
Status: Accepted
|
||||
|
||||
## Checklist
|
||||
|
||||
- Validate all management payloads with Zod.
|
||||
- Reject malformed scope assignment updates with status 400.
|
||||
- Reject deleting an in-use proxy with status 409 unless forced.
|
||||
- Never expose proxy username/password in list responses by default.
|
||||
- Never log raw credentials or token values.
|
||||
- Keep error responses free from internal stack traces.
|
||||
- Protect management endpoints with existing auth middleware policy.
|
||||
- Audit mutating operations: create/update/delete/assign/migrate.
|
||||
- Ensure resolver fallback to legacy config while migration is in transition.
|
||||
@@ -1,37 +0,0 @@
|
||||
# ADR-001: Next.js as the Foundation for an AI Gateway
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute is an AI routing gateway that translates, forwards, and manages requests across 20+ LLM providers. We needed a framework that could serve both the API proxy layer and a management dashboard from a single codebase.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **Express.js only** — Simpler proxy, but requires separate frontend tooling
|
||||
- **Fastify** — Fast, but no built-in SSR/dashboard support
|
||||
- **Next.js** — Unified full-stack framework with API routes, SSR, and static pages
|
||||
|
||||
## Decision
|
||||
|
||||
We chose Next.js because:
|
||||
|
||||
1. **Single deployment** — API routes (`/api/*`) and dashboard UI in one process
|
||||
2. **Middleware layer** — Native request interception for auth guards and request tracing
|
||||
3. **File-based routing** — Easy to map provider endpoints to handlers
|
||||
4. **Built-in TypeScript** — Type safety across the entire codebase
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- One `npm run build` produces both API and UI
|
||||
- Middleware provides centralized auth and request tracing
|
||||
- Dashboard gets automatic code splitting and optimization
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Next.js middleware has limitations (no heavy imports, edge runtime constraints)
|
||||
- Serverless deployment model doesn't align with persistent WebSocket/SSE connections
|
||||
- Build times are longer than Express-only setups
|
||||
- The SSE proxy layer (`open-sse/`) operates outside Next.js conventions
|
||||
@@ -1,37 +0,0 @@
|
||||
# ADR-002: Hub-and-Spoke Translation with OpenAI as Intermediate Format
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute routes requests across 20+ providers, each with its own API format (OpenAI, Anthropic Messages, Google Gemini, AWS Bedrock, etc.). Direct provider-to-provider translation would require O(n²) translators.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **Direct translation** — Each pair needs a dedicated translator (n² complexity)
|
||||
- **Common intermediate format** — Translate to/from a canonical format (2n complexity)
|
||||
- **Protocol buffers** — Strong typing but heavy overhead for a proxy
|
||||
|
||||
## Decision
|
||||
|
||||
We use the **OpenAI Chat Completions format** as the canonical intermediate representation. All incoming requests are normalized to OpenAI format, processed, then translated to the target provider's format.
|
||||
|
||||
```
|
||||
Client → [any format] → OpenAI canonical → [target format] → Provider
|
||||
Provider → [response] → OpenAI canonical → [original format] → Client
|
||||
```
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- Only 2 translators per provider (inbound + outbound) instead of n² pairs
|
||||
- OpenAI format is the de facto standard — most clients already use it
|
||||
- Adding a new provider requires only implementing one translator pair
|
||||
- Streaming (SSE) works consistently through the canonical format
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Some provider-specific features may be lost in translation
|
||||
- The double translation adds latency (typically < 5ms)
|
||||
- OpenAI format changes require updating the canonical representation
|
||||
@@ -1,39 +0,0 @@
|
||||
# ADR-003: Dual Storage — SQLite Primary with JSON Migration Path
|
||||
|
||||
## Status: Accepted
|
||||
|
||||
## Context
|
||||
|
||||
OmniRoute originally used LowDB (JSON file) for all persistence. As the project grew, JSON-based storage became a bottleneck for concurrent access, querying, and data integrity.
|
||||
|
||||
**Alternatives considered:**
|
||||
|
||||
- **LowDB only** — Simple but no concurrent access, no ACID, no querying
|
||||
- **SQLite only** — Fast, ACID-compliant, but breaks existing deployments
|
||||
- **PostgreSQL** — Production-grade but requires external dependency
|
||||
- **Dual storage with migration** — SQLite primary + automatic JSON migration
|
||||
|
||||
## Decision
|
||||
|
||||
We migrated to **SQLite as the primary store** with an automatic one-time migration from `db.json`:
|
||||
|
||||
1. On startup, if `db.json` exists and SQLite is empty, auto-migrate all data
|
||||
2. All new reads/writes go through SQLite
|
||||
3. The `db.json` file is preserved but no longer written to
|
||||
|
||||
Settings remain in a hybrid model where LowDB handles simple key-value configuration for backward compatibility.
|
||||
|
||||
## Consequences
|
||||
|
||||
**Positive:**
|
||||
|
||||
- ACID transactions for provider connections, API keys, and usage data
|
||||
- Proper SQL queries for analytics and log filtering
|
||||
- Concurrent read/write safety via WAL mode
|
||||
- Zero-downtime migration from JSON — users upgrade transparently
|
||||
|
||||
**Negative:**
|
||||
|
||||
- Two storage engines to maintain (SQLite + LowDB for settings)
|
||||
- Migration code must handle edge cases and partial data
|
||||
- SQLite binary dependency needed in deployment environments
|
||||
@@ -1,36 +0,0 @@
|
||||
# Task 01 — Home Page (Dashboard)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `home`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/page.tsx` | 17 | 0 (wrapper) |
|
||||
| `src/app/(dashboard)/dashboard/HomePageClient.tsx` | 500 | ~25 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
### HomePageClient.tsx
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 138 | "Quick Start" | `home.quickStart` | "Início Rápido" |
|
||||
| 242 | "Providers Overview" | `home.providersOverview` | "Visão Geral dos Provedores" |
|
||||
| 436 | "No models available for this provider." | `home.noModelsAvailable` | "Nenhum modelo disponível para este provedor." |
|
||||
| — | "Total Requests" | `home.totalRequests` | "Total de Requisições" |
|
||||
| — | "Active Providers" | `home.activeProviders` | "Provedores Ativos" |
|
||||
| — | "Success Rate" | `home.successRate` | "Taxa de Sucesso" |
|
||||
| — | "Avg Latency" | `home.avgLatency` | "Latência Média" |
|
||||
| — | "Configure Endpoint" | `home.configureEndpoint` | "Configurar Endpoint" |
|
||||
| — | "Add Provider" | `home.addProvider` | "Adicionar Provedor" |
|
||||
| — | "View Docs" | `home.viewDocs` | "Ver Documentação" |
|
||||
| — | "Copied!" | `common.copied` | ✅ já existe |
|
||||
| — | "requests" | `home.requests` | "requisições" |
|
||||
| — | "models" | `home.models` | "modelos" |
|
||||
| — | "accounts" | `home.accounts` | "contas" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json` (namespace `home`)
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` no `HomePageClient.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,25 +0,0 @@
|
||||
# Task 02 — Analytics Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `analytics`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/analytics/page.tsx` | 46 | ~8 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 11 | "Monitor your API usage patterns..." | `analytics.overviewDescription` | "Monitore padrões de uso da API..." |
|
||||
| 13 | "Run evaluation suites to test..." | `analytics.evalsDescription` | "Execute suítes de avaliação..." |
|
||||
| 24 | "Analytics" | `analytics.title` | "Análises" |
|
||||
| 32 | "Overview" | `analytics.overview` | "Visão Geral" |
|
||||
| 33 | "Evals" | `analytics.evals` | "Avaliações" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` em `page.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,31 +0,0 @@
|
||||
# Task 03 — API Manager Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `apiManager`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/api-manager/ApiManagerPageClient.tsx` | ~400 | ~20 |
|
||||
|
||||
## Strings a Traduzir (levantamento parcial — abrir código para completar)
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "API Keys" | `apiManager.title` | "Chaves de API" |
|
||||
| "Create API Key" | `apiManager.createKey` | "Criar Chave de API" |
|
||||
| "Name" | `apiManager.name` | "Nome" |
|
||||
| "Key" | `apiManager.key` | "Chave" |
|
||||
| "Created" | `apiManager.created` | "Criado em" |
|
||||
| "Last Used" | `apiManager.lastUsed` | "Último Uso" |
|
||||
| "Actions" | `apiManager.actions` | "Ações" |
|
||||
| "Delete" | `common.delete` | ✅ já existe |
|
||||
| "No API keys found" | `apiManager.noKeys` | "Nenhuma chave de API encontrada" |
|
||||
| ~11 strings adicionais | — | Levantar no código |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar todas as strings do `ApiManagerPageClient.tsx`
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,31 +0,0 @@
|
||||
# Task 04 — Audit Log Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `auditLog`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/audit-log/page.tsx` | 241 | ~12 |
|
||||
| `src/app/(dashboard)/dashboard/logs/AuditLogTab.tsx` | ~100 | ~3 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Audit Log" | `auditLog.title` | "Log de Auditoria" |
|
||||
| "Search actions..." | `auditLog.searchPlaceholder` | "Buscar ações..." |
|
||||
| "Action" | `auditLog.action` | "Ação" |
|
||||
| "Actor" | `auditLog.actor` | "Autor" |
|
||||
| "Target" | `auditLog.target` | "Alvo" |
|
||||
| "Details" | `auditLog.details` | "Detalhes" |
|
||||
| "IP Address" | `auditLog.ipAddress` | "Endereço IP" |
|
||||
| "Timestamp" | `auditLog.timestamp` | "Data/Hora" |
|
||||
| "No audit entries found" | `auditLog.noEntries` | "Nenhum registro de auditoria" |
|
||||
| "Load More" | `auditLog.loadMore` | "Carregar Mais" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings em `audit-log/page.tsx` e `AuditLogTab.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,37 +0,0 @@
|
||||
# Task 05 — CLI Tools Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `cliTools`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `cli-tools/components/AntigravityToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/ClaudeToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/ClineToolCard.tsx` | ~4 |
|
||||
| `cli-tools/components/CodexToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/DefaultToolCard.tsx` | ~3 |
|
||||
| `cli-tools/components/DroidToolCard.tsx` | ~2 |
|
||||
| `cli-tools/components/KiloToolCard.tsx` | ~4 |
|
||||
| `cli-tools/components/OpenClawToolCard.tsx` | ~2 |
|
||||
|
||||
## Strings comuns entre Tool Cards
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Status" | `cliTools.status` | "Status" |
|
||||
| "Connected" | `cliTools.connected` | "Conectado" |
|
||||
| "Not Connected" | `cliTools.notConnected` | "Não Conectado" |
|
||||
| "Configure" | `cliTools.configure` | "Configurar" |
|
||||
| "Test Connection" | `cliTools.testConnection` | "Testar Conexão" |
|
||||
| "Models" | `cliTools.models` | "Modelos" |
|
||||
| "Map Models" | `cliTools.mapModels` | "Mapear Modelos" |
|
||||
| "Save" | `common.save` | ✅ já existe |
|
||||
| "Cancel" | `common.cancel` | ✅ já existe |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings de cada ToolCard
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,34 +0,0 @@
|
||||
# Task 06 — Combos Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `combos`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/combos/page.tsx` | ~1000 | ~20 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 207 | "Combos" | `combos.title` | "Combos" |
|
||||
| 372 | "No models" | `combos.noModels` | "Sem modelos" |
|
||||
| 747 | "Routing Strategy" | `combos.routingStrategy` | "Estratégia de Roteamento" |
|
||||
| 791 | "Models" | `combos.models` | "Modelos" |
|
||||
| 807 | "No models added yet" | `combos.noModelsYet` | "Nenhum modelo adicionado" |
|
||||
| 922 | "Max Retries" | `combos.maxRetries` | "Máximo de Tentativas" |
|
||||
| 959 | "Timeout (ms)" | `combos.timeout` | "Timeout (ms)" |
|
||||
| 977 | "Healthcheck" | `combos.healthcheck` | "Verificação de Saúde" |
|
||||
| — | "Create Combo" | `combos.create` | "Criar Combo" |
|
||||
| — | "Edit Combo" | `combos.edit` | "Editar Combo" |
|
||||
| — | "Delete Combo" | `combos.deleteCombo` | "Excluir Combo" |
|
||||
| — | "Add Model" | `combos.addModel` | "Adicionar Modelo" |
|
||||
| — | "Priority" | `combos.priority` | "Prioridade" |
|
||||
| — | "Fallback" | `combos.fallback` | "Fallback" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves no `en.json`
|
||||
- [ ] Adicionar traduções no `pt-BR.json`
|
||||
- [ ] Substituir strings por `t()` em `combos/page.tsx`
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,23 +0,0 @@
|
||||
# Task 07 — Costs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `costs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/costs/page.tsx` | ~200 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Costs" | `costs.title` | "Custos" |
|
||||
| "Total Cost" | `costs.totalCost` | "Custo Total" |
|
||||
| "Cost Breakdown" | `costs.breakdown` | "Detalhamento de Custos" |
|
||||
| "No cost data" | `costs.noData` | "Sem dados de custo" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas do código
|
||||
- [ ] Adicionar chaves no `en.json` / `pt-BR.json`
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,30 +0,0 @@
|
||||
# Task 08 — Endpoint Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `endpoint`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/endpoint/EndpointPageClient.tsx` | ~750 | ~20 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| Linha | String EN | Chave i18n | String PT-BR |
|
||||
|-------|-----------|------------|--------------|
|
||||
| 320 | "API Endpoint" | `endpoint.title` | "Endpoint da API" |
|
||||
| 403 | "Available Endpoints" | `endpoint.available` | "Endpoints Disponíveis" |
|
||||
| 561 | "Cloud Proxy" | `endpoint.cloudProxy` | "Proxy na Nuvem" |
|
||||
| 632 | "Note" | `endpoint.note` | "Nota" |
|
||||
| 717 | "Warning" | `endpoint.warning` | "Aviso" |
|
||||
| 740 | "Are you sure you want to disable cloud proxy?" | `endpoint.disableConfirm` | "Tem certeza que deseja desativar o proxy na nuvem?" |
|
||||
| — | "Copy" | `common.copy` | ✅ já existe |
|
||||
| — | "Base URL" | `endpoint.baseUrl` | "URL Base" |
|
||||
| — | "Connected" | `endpoint.connected` | "Conectado" |
|
||||
| — | "Enable" | `endpoint.enable` | "Ativar" |
|
||||
| — | "Disable" | `endpoint.disable` | "Desativar" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings restantes
|
||||
- [ ] Adicionar chaves no `en.json` / `pt-BR.json`
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,30 +0,0 @@
|
||||
# Task 09 — Health Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `health`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/health/page.tsx` | ~350 | ~15 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "System Health" | `health.title` | "Saúde do Sistema" |
|
||||
| "Healthy" | `health.healthy` | "Saudável" |
|
||||
| "Degraded" | `health.degraded` | "Degradado" |
|
||||
| "Down" | `health.down` | "Offline" |
|
||||
| "Uptime" | `health.uptime` | "Tempo Ativo" |
|
||||
| "Memory" | `health.memory` | "Memória" |
|
||||
| "CPU" | `health.cpu` | "CPU" |
|
||||
| "Database" | `health.database` | "Banco de Dados" |
|
||||
| "Last Check" | `health.lastCheck` | "Última Verificação" |
|
||||
| "Refresh" | `common.refresh` | ✅ já existe |
|
||||
| ~5 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings restantes
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,24 +0,0 @@
|
||||
# Task 10 — Limits Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `limits`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/limits/page.tsx` | ~150 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Limits & Quotas" | `limits.title` | "Limites e Cotas" |
|
||||
| "Rate Limit" | `limits.rateLimit` | "Limite de Taxa" |
|
||||
| "Provider" | `limits.provider` | "Provedor" |
|
||||
| "Remaining" | `limits.remaining` | "Restante" |
|
||||
| "Reset" | `limits.reset` | "Reiniciar" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,24 +0,0 @@
|
||||
# Task 11 — Logs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `logs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/logs/` | ~200 | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Logs" | `logs.title` | "Logs" |
|
||||
| "Request Logs" | `logs.requestLogs` | "Logs de Requisições" |
|
||||
| "Proxy Logs" | `logs.proxyLogs` | "Logs do Proxy" |
|
||||
| "Audit Log" | `logs.auditLog` | "Log de Auditoria" |
|
||||
| "Console" | `logs.console` | "Console" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,26 +0,0 @@
|
||||
# Task 12 — Onboarding Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `onboarding`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Linhas | Strings |
|
||||
|---------|--------|---------|
|
||||
| `src/app/(dashboard)/dashboard/onboarding/page.tsx` | ~300 | ~10 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Welcome to OmniRoute" | `onboarding.welcome` | "Bem-vindo ao OmniRoute" |
|
||||
| "Set Password" | `onboarding.setPassword` | "Definir Senha" |
|
||||
| "Add Provider" | `onboarding.addProvider` | "Adicionar Provedor" |
|
||||
| "Get Started" | `onboarding.getStarted` | "Começar" |
|
||||
| "Skip" | `onboarding.skip` | "Pular" |
|
||||
| "Next" | `common.next` | ✅ já existe |
|
||||
| ~4 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,35 +0,0 @@
|
||||
# Task 13 — Providers Pages
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `providers`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `providers/page.tsx` | ~5 |
|
||||
| `providers/[id]/page.tsx` | ~12 |
|
||||
| `providers/new/page.tsx` | ~3 |
|
||||
| `providers/components/ModelAvailabilityPanel.tsx` | ~3 |
|
||||
| `providers/components/ModelAvailabilityBadge.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Providers" | `providers.title` | "Provedores" |
|
||||
| "Add Provider" | `providers.add` | "Adicionar Provedor" |
|
||||
| "Edit Provider" | `providers.edit` | "Editar Provedor" |
|
||||
| "Test Connection" | `providers.testConnection` | "Testar Conexão" |
|
||||
| "Connected" | `providers.connected` | "Conectado" |
|
||||
| "Disconnected" | `providers.disconnected` | "Desconectado" |
|
||||
| "Models" | `providers.models` | "Modelos" |
|
||||
| "Accounts" | `providers.accounts` | "Contas" |
|
||||
| "Delete Provider" | `providers.deleteProvider` | "Excluir Provedor" |
|
||||
| "No providers configured" | `providers.noProviders` | "Nenhum provedor configurado" |
|
||||
| "Model Availability" | `providers.modelAvailability` | "Disponibilidade de Modelos" |
|
||||
| ~9 strings adicionais | — | Levantar |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas de todos os arquivos
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,51 +0,0 @@
|
||||
# Task 14 — Settings Page (MAIOR TAREFA)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `settings`
|
||||
|
||||
## Arquivos (20 componentes!)
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `settings/components/AppearanceTab.tsx` | ~4 |
|
||||
| `settings/components/CacheStatsCard.tsx` | ~4 |
|
||||
| `settings/components/ComboDefaultsTab.tsx` | ~8 |
|
||||
| `settings/components/FallbackChainsEditor.tsx` | ~2 |
|
||||
| `settings/components/IPFilterSection.tsx` | ~2 |
|
||||
| `settings/components/PoliciesPanel.tsx` | ~5 |
|
||||
| `settings/components/PricingTab.tsx` | ~8 |
|
||||
| `settings/components/ProxyTab.tsx` | ~2 |
|
||||
| `settings/components/ResilienceTab.tsx` | ~7 |
|
||||
| `settings/components/RoutingTab.tsx` | ~4 |
|
||||
| `settings/components/SecurityTab.tsx` | ~5 |
|
||||
| `settings/components/SessionInfoCard.tsx` | ~5 |
|
||||
| `settings/components/SystemPromptTab.tsx` | ~2 |
|
||||
| `settings/components/SystemStorageTab.tsx` | ~8 |
|
||||
| `settings/components/ThinkingBudgetTab.tsx` | ~5 |
|
||||
| `settings/pricing/page.tsx` | ~17 |
|
||||
|
||||
## Strings a Traduzir (amostra)
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "General" | `settings.general` | "Geral" |
|
||||
| "Security" | `settings.security` | "Segurança" |
|
||||
| "Appearance" | `settings.appearance` | "Aparência" |
|
||||
| "Routing" | `settings.routing` | "Roteamento" |
|
||||
| "Cache" | `settings.cache` | "Cache" |
|
||||
| "Resilience" | `settings.resilience` | "Resiliência" |
|
||||
| "System Prompt" | `settings.systemPrompt` | "Prompt do Sistema" |
|
||||
| "Thinking Budget" | `settings.thinkingBudget` | "Orçamento de Raciocínio" |
|
||||
| "Proxy" | `settings.proxy` | "Proxy" |
|
||||
| "Pricing" | `settings.pricing` | "Preços" |
|
||||
| "Storage" | `settings.storage` | "Armazenamento" |
|
||||
| "Policies" | `settings.policies` | "Políticas" |
|
||||
| "IP Filter" | `settings.ipFilter` | "Filtro de IP" |
|
||||
| "Combo Defaults" | `settings.comboDefaults` | "Padrões de Combo" |
|
||||
| "Fallback Chains" | `settings.fallbackChains` | "Cadeias de Fallback" |
|
||||
| ~40 strings adicionais | — | Levantar em cada tab |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings de CADA componente (16 arquivos)
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em todos os 16 arquivos
|
||||
- [ ] Testar cada aba em EN e PT-BR
|
||||
@@ -1,41 +0,0 @@
|
||||
# Task 15 — Translator Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `translator`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `translator/components/LiveMonitorMode.tsx` | ~11 |
|
||||
| `translator/components/PlaygroundMode.tsx` | ~5 |
|
||||
| `translator/components/TestBenchMode.tsx` | ~3 |
|
||||
| `translator/components/ChatTesterMode.tsx` | ~4 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Real-Time Translation Activity" | `translator.realtime` | "Atividade de Tradução em Tempo Real" |
|
||||
| "Chat Tester" | `translator.chatTester` | "Testador de Chat" |
|
||||
| "Test Bench" | `translator.testBench` | "Bancada de Testes" |
|
||||
| "Recent Translations" | `translator.recentTranslations` | "Traduções Recentes" |
|
||||
| "No translations yet" | `translator.noTranslations` | "Nenhuma tradução ainda" |
|
||||
| "Time" | `translator.time` | "Tempo" |
|
||||
| "Source" | `translator.source` | "Origem" |
|
||||
| "Target" | `translator.target` | "Destino" |
|
||||
| "Model" | `translator.model` | "Modelo" |
|
||||
| "Status" | `translator.status` | "Status" |
|
||||
| "Latency" | `translator.latency` | "Latência" |
|
||||
| "Format Converter" | `translator.formatConverter` | "Conversor de Formato" |
|
||||
| "Input" | `translator.input` | "Entrada" |
|
||||
| "Output" | `translator.output` | "Saída" |
|
||||
| "Example Templates" | `translator.exampleTemplates` | "Modelos de Exemplo" |
|
||||
| "Compatibility Tester" | `translator.compatibilityTester` | "Testador de Compatibilidade" |
|
||||
| "Compatibility Report" | `translator.compatibilityReport` | "Relatório de Compatibilidade" |
|
||||
| "Pipeline Debugger" | `translator.pipelineDebugger` | "Depurador de Pipeline" |
|
||||
| "Translation Pipeline" | `translator.translationPipeline` | "Pipeline de Tradução" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,57 +0,0 @@
|
||||
# Task 16 — Usage Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `usage`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `usage/components/BudgetTab.tsx` | ~4 |
|
||||
| `usage/components/BudgetTelemetryCards.tsx` | ~9 |
|
||||
| `usage/components/EvalsTab.tsx` | ~6 |
|
||||
| `usage/components/RateLimitStatus.tsx` | ~2 |
|
||||
| `usage/components/SessionsTab.tsx` | ~7 |
|
||||
| `usage/components/ProviderLimits/index.tsx` | ~7 |
|
||||
| `usage/components/ProviderLimits/ProviderLimitCard.tsx` | ~1 |
|
||||
| `usage/components/ProviderLimits/QuotaTable.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | Chave i18n | String PT-BR |
|
||||
|-----------|------------|--------------|
|
||||
| "Budget Management" | `usage.budgetManagement` | "Gerenciamento de Orçamento" |
|
||||
| "API Key" | `usage.apiKey` | "Chave de API" |
|
||||
| "This Month" | `usage.thisMonth` | "Este Mês" |
|
||||
| "Set Limits" | `usage.setLimits` | "Definir Limites" |
|
||||
| "Total requests" | `usage.totalRequests` | "Total de requisições" |
|
||||
| "No data yet" | `usage.noData` | "Sem dados ainda" |
|
||||
| "Entries" | `usage.entries` | "Entradas" |
|
||||
| "Hit Rate" | `usage.hitRate` | "Taxa de Acerto" |
|
||||
| "Circuit Breakers" | `usage.circuitBreakers` | "Disjuntores" |
|
||||
| "Locked IPs" | `usage.lockedIPs` | "IPs Bloqueados" |
|
||||
| "How It Works" | `usage.howItWorks` | "Como Funciona" |
|
||||
| "Define" | `usage.define` | "Definir" |
|
||||
| "Run" | `usage.run` | "Executar" |
|
||||
| "Evaluate" | `usage.evaluate` | "Avaliar" |
|
||||
| "Evaluation Suites" | `usage.evalSuites` | "Suítes de Avaliação" |
|
||||
| "Model Evaluations" | `usage.modelEvals` | "Avaliações de Modelos" |
|
||||
| "Model Lockouts" | `usage.modelLockouts` | "Bloqueios de Modelo" |
|
||||
| "No models currently locked" | `usage.noLockouts` | "Nenhum modelo bloqueado" |
|
||||
| "Active Sessions" | `usage.activeSessions` | "Sessões Ativas" |
|
||||
| "No active sessions" | `usage.noSessions` | "Sem sessões ativas" |
|
||||
| "Session" | `usage.session` | "Sessão" |
|
||||
| "Age" | `usage.age` | "Idade" |
|
||||
| "Requests" | `usage.requests` | "Requisições" |
|
||||
| "Connection" | `usage.connection` | "Conexão" |
|
||||
| "Provider Limits" | `usage.providerLimits` | "Limites do Provedor" |
|
||||
| "No Providers Connected" | `usage.noProviders` | "Nenhum Provedor Conectado" |
|
||||
| "Account" | `usage.account` | "Conta" |
|
||||
| "Model Quotas" | `usage.modelQuotas` | "Cotas de Modelo" |
|
||||
| "Last Used" | `usage.lastUsed` | "Último Uso" |
|
||||
| "Actions" | `usage.actions` | "Ações" |
|
||||
| "No quota data" | `usage.noQuota` | "Sem dados de cota" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,44 +0,0 @@
|
||||
# Task 17 — Shared Modals
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `modals`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/OAuthModal.tsx` | ~6 |
|
||||
| `shared/components/KiroAuthModal.tsx` | ~10 |
|
||||
| `shared/components/KiroSocialOAuthModal.tsx` | ~3 |
|
||||
| `shared/components/CursorAuthModal.tsx` | ~2 |
|
||||
| `shared/components/PricingModal.tsx` | ~10 |
|
||||
| `shared/components/ModelSelectModal.tsx` | ~2 |
|
||||
| `shared/components/ProxyConfigModal.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Waiting for Authorization" | "Aguardando Autorização" |
|
||||
| "Verification URL" | "URL de Verificação" |
|
||||
| "Your Code" | "Seu Código" |
|
||||
| "Remote access:" | "Acesso remoto:" |
|
||||
| "Connected Successfully!" | "Conectado com Sucesso!" |
|
||||
| "Connection Failed" | "Falha na Conexão" |
|
||||
| "Choose your authentication method:" | "Escolha seu método de autenticação:" |
|
||||
| "AWS Builder ID" | "AWS Builder ID" |
|
||||
| "AWS IAM Identity Center" | "AWS IAM Identity Center" |
|
||||
| "Google Account" | "Conta Google" |
|
||||
| "GitHub Account" | "Conta GitHub" |
|
||||
| "Import Token" | "Importar Token" |
|
||||
| "Auto-detecting tokens..." | "Detectando tokens automaticamente..." |
|
||||
| "Pricing Configuration" | "Configuração de Preços" |
|
||||
| "Loading pricing data..." | "Carregando dados de preços..." |
|
||||
| "Model" / "Input" / "Output" / "Cached" | "Modelo" / "Entrada" / "Saída" / "Em Cache" |
|
||||
| "Combos" | "Combos" |
|
||||
| "No models found" | "Nenhum modelo encontrado" |
|
||||
| "Connected" | "Conectado" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada modal
|
||||
- [ ] Testar cada modal em EN e PT-BR
|
||||
@@ -1,37 +0,0 @@
|
||||
# Task 18 — Shared Loggers
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `loggers`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/RequestLoggerV2.tsx` | ~12 |
|
||||
| `shared/components/RequestLoggerDetail.tsx` | ~4 |
|
||||
| `shared/components/ProxyLogger.tsx` | ~7 |
|
||||
| `shared/components/ProxyLogDetail.tsx` | ~6 |
|
||||
| `shared/components/ConsoleLogViewer.tsx` | ~2 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "All Providers" | "Todos os Provedores" |
|
||||
| "All Models" | "Todos os Modelos" |
|
||||
| "All Accounts" | "Todas as Contas" |
|
||||
| "All API Keys" | "Todas as Chaves de API" |
|
||||
| "Newest" / "Oldest" | "Mais Recente" / "Mais Antigo" |
|
||||
| "Model A-Z" / "Model Z-A" | "Modelo A-Z" / "Modelo Z-A" |
|
||||
| "Columns" | "Colunas" |
|
||||
| "Loading logs..." | "Carregando logs..." |
|
||||
| "All Types" | "Todos os Tipos" |
|
||||
| "All Levels" | "Todos os Níveis" |
|
||||
| "Proxy Event" | "Evento do Proxy" |
|
||||
| "Time" / "Model" / "Combo" | "Tempo" / "Modelo" / "Combo" |
|
||||
| "No log entries found" | "Nenhuma entrada de log encontrada" |
|
||||
| "No payload data available" | "Nenhum dado de payload disponível" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada logger
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,36 +0,0 @@
|
||||
# Task 19 — Shared Charts & Stats
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `stats`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `shared/components/UsageStats.tsx` | ~6 |
|
||||
| `shared/components/analytics/charts.tsx` | ~15 |
|
||||
| `shared/components/TokenHealthBadge.tsx` | ~6 |
|
||||
| `shared/components/SystemMonitor.tsx` | ~1 |
|
||||
| `shared/components/Footer.tsx` | ~3 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Usage Overview" | "Visão Geral de Uso" |
|
||||
| "Output Tokens" | "Tokens de Saída" |
|
||||
| "Total Cost" | "Custo Total" |
|
||||
| "Usage by Model" | "Uso por Modelo" |
|
||||
| "Usage by Account" | "Uso por Conta" |
|
||||
| "Failed to load usage statistics." | "Falha ao carregar estatísticas." |
|
||||
| "Token Health" | "Saúde dos Tokens" |
|
||||
| "Total OAuth" | "Total OAuth" |
|
||||
| "Healthy" / "Errored" / "Warning" | "Saudável" / "Com Erro" / "Aviso" |
|
||||
| "Last check" | "Última verificação" |
|
||||
| "No data" / "Share" | "Sem dados" / "Compartilhar" |
|
||||
| "Unable to load system metrics" | "Não foi possível carregar métricas" |
|
||||
| "Product" / "Resources" / "Company" (Footer) | "Produto" / "Recursos" / "Empresa" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada componente
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,36 +0,0 @@
|
||||
# Task 20 — Login & Auth Pages
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `auth`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/login/page.tsx` | ~8 |
|
||||
| `src/app/forgot-password/page.tsx` | ~3 |
|
||||
| `src/app/callback/page.tsx` | ~5 |
|
||||
| `src/app/forbidden/page.tsx` | ~1 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Welcome" | "Bem-vindo" |
|
||||
| "OmniRoute" | "OmniRoute" (não traduzir) |
|
||||
| "Sign in" | "Entrar" |
|
||||
| "Enter your password to continue" | "Digite sua senha para continuar" |
|
||||
| "Password" | "Senha" |
|
||||
| "Unified AI API Proxy" | "Proxy Unificado de API de IA" |
|
||||
| "Loading..." | "Carregando..." |
|
||||
| "Password protection is not enabled" | "Proteção por senha não está ativada" |
|
||||
| "Reset Password" | "Redefinir Senha" |
|
||||
| "Choose a method to recover access" | "Escolha um método para recuperar acesso" |
|
||||
| "Processing..." | "Processando..." |
|
||||
| "Authorization Successful!" | "Autorização bem-sucedida!" |
|
||||
| "Copy This URL" | "Copiar esta URL" |
|
||||
| "Access Denied" | "Acesso Negado" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` em cada página
|
||||
- [ ] Testar em EN e PT-BR
|
||||
@@ -1,34 +0,0 @@
|
||||
# Task 21 — Landing Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `landing`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `landing/components/HeroSection.tsx` | ~3 |
|
||||
| `landing/components/Features.tsx` | ~10 |
|
||||
| `landing/components/HowItWorks.tsx` | ~5 |
|
||||
| `landing/components/GetStarted.tsx` | ~5 |
|
||||
| `landing/components/Navigation.tsx` | ~2 |
|
||||
| `landing/components/FlowAnimation.tsx` | ~2 |
|
||||
| `landing/components/Footer.tsx` | ~5 |
|
||||
|
||||
## Strings a Traduzir (amostra)
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "All AI Providers" | "Todos os Provedores de IA" |
|
||||
| "One Endpoint" | "Um Endpoint" |
|
||||
| "Powerful Features" | "Recursos Poderosos" |
|
||||
| "How OmniRoute Works" | "Como o OmniRoute Funciona" |
|
||||
| "Install OmniRoute" | "Instalar o OmniRoute" |
|
||||
| "Open Dashboard" | "Abrir Painel" |
|
||||
| "Route Requests" | "Rotear Requisições" |
|
||||
| "Data Location:" | "Local dos Dados:" |
|
||||
| "Product" / "Resources" / "Legal" | "Produto" / "Recursos" / "Legal" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Levantar strings completas de cada componente
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,32 +0,0 @@
|
||||
# Task 22 — Docs Page
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `docs`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/docs/page.tsx` | ~25 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Quick Start" | "Início Rápido" |
|
||||
| "Features" | "Recursos" |
|
||||
| "Supported Providers" | "Provedores Suportados" |
|
||||
| "Common Use Cases" | "Casos de Uso Comuns" |
|
||||
| "Client Compatibility" | "Compatibilidade de Clientes" |
|
||||
| "Cherry Studio" | "Cherry Studio" (não traduzir) |
|
||||
| "Codex / GitHub Copilot Models" | "Modelos Codex / GitHub Copilot" |
|
||||
| "Cursor IDE" | "Cursor IDE" (não traduzir) |
|
||||
| "Claude Code / Antigravity" | "Claude Code / Antigravity" |
|
||||
| "API Reference" | "Referência da API" |
|
||||
| "Method" / "Path" / "Notes" | "Método" / "Caminho" / "Notas" |
|
||||
| "Model Prefixes" | "Prefixos de Modelo" |
|
||||
| "Prefix" / "Provider" / "Type" | "Prefixo" / "Provedor" / "Tipo" |
|
||||
| "Troubleshooting" | "Solução de Problemas" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
@@ -1,31 +0,0 @@
|
||||
# Task 23 — Legal Pages (Privacy & Terms)
|
||||
|
||||
**Status:** `[ ]` Não iniciado
|
||||
**Namespace JSON:** `legal`
|
||||
|
||||
## Arquivos
|
||||
| Arquivo | Strings |
|
||||
|---------|---------|
|
||||
| `src/app/privacy/page.tsx` | ~10 |
|
||||
| `src/app/terms/page.tsx` | ~5 |
|
||||
|
||||
## Strings a Traduzir
|
||||
|
||||
| String EN | String PT-BR |
|
||||
|-----------|--------------|
|
||||
| "Privacy Policy" | "Política de Privacidade" |
|
||||
| "Terms of Service" | "Termos de Serviço" |
|
||||
| "Provider configurations" | "Configurações de provedores" |
|
||||
| "API keys" | "Chaves de API" |
|
||||
| "Usage logs" | "Logs de uso" |
|
||||
| "Application settings" | "Configurações do aplicativo" |
|
||||
| "View and export usage analytics" | "Visualizar e exportar análises de uso" |
|
||||
| "Clear usage history at any time" | "Limpar histórico de uso a qualquer momento" |
|
||||
| "Configure log retention policies" | "Configurar políticas de retenção de logs" |
|
||||
| "Back up and restore your database" | "Fazer backup e restaurar seu banco de dados" |
|
||||
|
||||
## Checklist
|
||||
- [ ] Adicionar chaves / traduções
|
||||
- [ ] Substituir por `t()` e testar
|
||||
|
||||
> **Nota:** Textos legais podem requerer revisão jurídica para tradução formal.
|
||||
@@ -1,51 +0,0 @@
|
||||
# i18n Translation Tasks
|
||||
|
||||
Cada arquivo `.md` nesta pasta representa **uma tarefa de tradução** para uma página ou componente do OmniRoute.
|
||||
|
||||
## Status Legend
|
||||
|
||||
- `[ ]` — Não iniciado
|
||||
- `[/]` — Em progresso
|
||||
- `[x]` — Concluído
|
||||
|
||||
## Dashboard Pages (~260 strings)
|
||||
|
||||
| # | Tarefa | Arquivo | Strings | Status |
|
||||
| --- | ---------------------------------- | ----------------------------------------------------- | ------- | ------ |
|
||||
| 01 | [Home](./01-home.md) | `HomePageClient.tsx` | ~25 | `[ ]` |
|
||||
| 02 | [Analytics](./02-analytics.md) | `analytics/page.tsx` | ~8 | `[ ]` |
|
||||
| 03 | [API Manager](./03-api-manager.md) | `api-manager/` | ~20 | `[ ]` |
|
||||
| 04 | [Audit Log](./04-audit-log.md) | `audit-log/page.tsx`, `logs/AuditLogTab.tsx` | ~15 | `[ ]` |
|
||||
| 05 | [CLI Tools](./05-cli-tools.md) | `cli-tools/components/*.tsx` | ~20 | `[ ]` |
|
||||
| 06 | [Combos](./06-combos.md) | `combos/page.tsx` | ~20 | `[ ]` |
|
||||
| 07 | [Costs](./07-costs.md) | `costs/page.tsx` | ~5 | `[ ]` |
|
||||
| 08 | [Endpoint](./08-endpoint.md) | `endpoint/EndpointPageClient.tsx` | ~20 | `[ ]` |
|
||||
| 09 | [Health](./09-health.md) | `health/page.tsx` | ~15 | `[ ]` |
|
||||
| 10 | [Limits](./10-limits.md) | `limits/page.tsx` | ~5 | `[ ]` |
|
||||
| 11 | [Logs](./11-logs.md) | `logs/` | ~5 | `[ ]` |
|
||||
| 12 | [Onboarding](./12-onboarding.md) | `onboarding/page.tsx` | ~10 | `[ ]` |
|
||||
| 13 | [Providers](./13-providers.md) | `providers/page.tsx`, `[id]/page.tsx`, `new/page.tsx` | ~20 | `[ ]` |
|
||||
| 14 | [Settings](./14-settings.md) | `settings/components/*.tsx` | ~55 | `[ ]` |
|
||||
| 15 | [Translator](./15-translator.md) | `translator/components/*.tsx` | ~25 | `[ ]` |
|
||||
| 16 | [Usage](./16-usage.md) | `usage/components/*.tsx` | ~35 | `[ ]` |
|
||||
|
||||
## Shared Components (~95 strings)
|
||||
|
||||
| # | Tarefa | Arquivo(s) | Strings | Status |
|
||||
| --- | ---------------------------------------------- | ---------------------------------------------------- | ------- | ------ |
|
||||
| 17 | [Shared Modals](./17-shared-modals.md) | `OAuthModal`, `KiroAuthModal`, `PricingModal`, etc. | ~40 | `[ ]` |
|
||||
| 18 | [Shared Loggers](./18-shared-loggers.md) | `RequestLoggerV2`, `ProxyLogger`, `ProxyLogDetail` | ~30 | `[ ]` |
|
||||
| 19 | [Shared Charts & Stats](./19-shared-charts.md) | `UsageStats`, `analytics/charts`, `TokenHealthBadge` | ~25 | `[ ]` |
|
||||
|
||||
## Non-Dashboard Pages (~75 strings)
|
||||
|
||||
| # | Tarefa | Arquivo(s) | Strings | Status |
|
||||
| --- | ---------------------------------- | ------------------------------------------------------- | ------- | ------ |
|
||||
| 20 | [Login & Auth](./20-login-auth.md) | `login/`, `forgot-password/`, `callback/`, `forbidden/` | ~20 | `[ ]` |
|
||||
| 21 | [Landing Page](./21-landing.md) | `landing/components/*.tsx` | ~25 | `[ ]` |
|
||||
| 22 | [Docs Page](./22-docs.md) | `docs/page.tsx` | ~25 | `[ ]` |
|
||||
| 23 | [Legal Pages](./23-legal.md) | `privacy/`, `terms/` | ~15 | `[ ]` |
|
||||
|
||||
---
|
||||
|
||||
**Total estimado: ~460 strings em 23 tarefas**
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
This directory contains machine-assisted translations based on the English docs.
|
||||
|
||||
- **API_REFERENCE.md**: 🇺🇸 [English](../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](./es/API_REFERENCE.md) | 🇫🇷 [Français](./fr/API_REFERENCE.md) | 🇮🇹 [Italiano](./it/API_REFERENCE.md) | 🇷🇺 [Русский](./ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](./zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](./de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](./in/API_REFERENCE.md) | 🇹🇭 [ไทย](./th/API_REFERENCE.md) | 🇺🇦 [Українська](./uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](./ar/API_REFERENCE.md) | 🇯🇵 [日本語](./ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](./vi/API_REFERENCE.md) | 🇧🇬 [Български](./bg/API_REFERENCE.md) | 🇩🇰 [Dansk](./da/API_REFERENCE.md) | 🇫🇮 [Suomi](./fi/API_REFERENCE.md) | 🇮🇱 [עברית](./he/API_REFERENCE.md) | 🇭🇺 [Magyar](./hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](./id/API_REFERENCE.md) | 🇰🇷 [한국어](./ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](./ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](./nl/API_REFERENCE.md) | 🇳🇴 [Norsk](./no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](./pt/API_REFERENCE.md) | 🇷🇴 [Română](./ro/API_REFERENCE.md) | 🇵🇱 [Polski](./pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](./sk/API_REFERENCE.md) | 🇸🇪 [Svenska](./sv/API_REFERENCE.md) | 🇵🇭 [Filipino](./phi/API_REFERENCE.md)
|
||||
- **ARCHITECTURE.md**: 🇺🇸 [English](../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](./es/ARCHITECTURE.md) | 🇫🇷 [Français](./fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](./it/ARCHITECTURE.md) | 🇷🇺 [Русский](./ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](./zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](./de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](./in/ARCHITECTURE.md) | 🇹🇭 [ไทย](./th/ARCHITECTURE.md) | 🇺🇦 [Українська](./uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](./ar/ARCHITECTURE.md) | 🇯🇵 [日本語](./ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](./vi/ARCHITECTURE.md) | 🇧🇬 [Български](./bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](./da/ARCHITECTURE.md) | 🇫🇮 [Suomi](./fi/ARCHITECTURE.md) | 🇮🇱 [עברית](./he/ARCHITECTURE.md) | 🇭🇺 [Magyar](./hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](./id/ARCHITECTURE.md) | 🇰🇷 [한국어](./ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](./ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](./nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](./no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](./pt/ARCHITECTURE.md) | 🇷🇴 [Română](./ro/ARCHITECTURE.md) | 🇵🇱 [Polski](./pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](./sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](./sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](./phi/ARCHITECTURE.md)
|
||||
- **CODEBASE_DOCUMENTATION.md**: 🇺🇸 [English](../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](./pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](./es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](./fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](./it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](./ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](./zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](./de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](./in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](./th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](./uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](./ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](./ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](./vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](./bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](./da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](./fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](./he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](./hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](./id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](./ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](./ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](./nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](./no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](./pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](./ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](./pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](./sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](./sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](./phi/CODEBASE_DOCUMENTATION.md)
|
||||
- **FEATURES.md**: 🇺🇸 [English](../FEATURES.md) | 🇧🇷 [Português (Brasil)](./pt-BR/FEATURES.md) | 🇪🇸 [Español](./es/FEATURES.md) | 🇫🇷 [Français](./fr/FEATURES.md) | 🇮🇹 [Italiano](./it/FEATURES.md) | 🇷🇺 [Русский](./ru/FEATURES.md) | 🇨🇳 [中文 (简体)](./zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](./de/FEATURES.md) | 🇮🇳 [हिन्दी](./in/FEATURES.md) | 🇹🇭 [ไทย](./th/FEATURES.md) | 🇺🇦 [Українська](./uk-UA/FEATURES.md) | 🇸🇦 [العربية](./ar/FEATURES.md) | 🇯🇵 [日本語](./ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](./vi/FEATURES.md) | 🇧🇬 [Български](./bg/FEATURES.md) | 🇩🇰 [Dansk](./da/FEATURES.md) | 🇫🇮 [Suomi](./fi/FEATURES.md) | 🇮🇱 [עברית](./he/FEATURES.md) | 🇭🇺 [Magyar](./hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](./id/FEATURES.md) | 🇰🇷 [한국어](./ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](./ms/FEATURES.md) | 🇳🇱 [Nederlands](./nl/FEATURES.md) | 🇳🇴 [Norsk](./no/FEATURES.md) | 🇵🇹 [Português (Portugal)](./pt/FEATURES.md) | 🇷🇴 [Română](./ro/FEATURES.md) | 🇵🇱 [Polski](./pl/FEATURES.md) | 🇸🇰 [Slovenčina](./sk/FEATURES.md) | 🇸🇪 [Svenska](./sv/FEATURES.md) | 🇵🇭 [Filipino](./phi/FEATURES.md)
|
||||
- **TROUBLESHOOTING.md**: 🇺🇸 [English](../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](./pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](./es/TROUBLESHOOTING.md) | 🇫🇷 [Français](./fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](./it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](./ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](./zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](./de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](./in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](./th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](./uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](./ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](./ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](./vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](./bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](./da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](./fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](./he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](./hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](./id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](./ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](./ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](./nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](./no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](./pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](./ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](./pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](./sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](./sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](./phi/TROUBLESHOOTING.md)
|
||||
- **USER_GUIDE.md**: 🇺🇸 [English](../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](./es/USER_GUIDE.md) | 🇫🇷 [Français](./fr/USER_GUIDE.md) | 🇮🇹 [Italiano](./it/USER_GUIDE.md) | 🇷🇺 [Русский](./ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](./zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](./de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](./in/USER_GUIDE.md) | 🇹🇭 [ไทย](./th/USER_GUIDE.md) | 🇺🇦 [Українська](./uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](./ar/USER_GUIDE.md) | 🇯🇵 [日本語](./ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](./vi/USER_GUIDE.md) | 🇧🇬 [Български](./bg/USER_GUIDE.md) | 🇩🇰 [Dansk](./da/USER_GUIDE.md) | 🇫🇮 [Suomi](./fi/USER_GUIDE.md) | 🇮🇱 [עברית](./he/USER_GUIDE.md) | 🇭🇺 [Magyar](./hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](./id/USER_GUIDE.md) | 🇰🇷 [한국어](./ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](./ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](./nl/USER_GUIDE.md) | 🇳🇴 [Norsk](./no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](./pt/USER_GUIDE.md) | 🇷🇴 [Română](./ro/USER_GUIDE.md) | 🇵🇱 [Polski](./pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](./sk/USER_GUIDE.md) | 🇸🇪 [Svenska](./sv/USER_GUIDE.md) | 🇵🇭 [Filipino](./phi/USER_GUIDE.md)
|
||||
- **API_REFERENCE.md**: 🇺🇸 [English](../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](./es/API_REFERENCE.md) | 🇫🇷 [Français](./fr/API_REFERENCE.md) | 🇮🇹 [Italiano](./it/API_REFERENCE.md) | 🇷🇺 [Русский](./ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](./zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](./de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](./in/API_REFERENCE.md) | 🇹🇭 [ไทย](./th/API_REFERENCE.md) | 🇺🇦 [Українська](./uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](./ar/API_REFERENCE.md) | 🇯🇵 [日本語](./ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](./vi/API_REFERENCE.md) | 🇧🇬 [Български](./bg/API_REFERENCE.md) | 🇩🇰 [Dansk](./da/API_REFERENCE.md) | 🇫🇮 [Suomi](./fi/API_REFERENCE.md) | 🇮🇱 [עברית](./he/API_REFERENCE.md) | 🇭🇺 [Magyar](./hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](./id/API_REFERENCE.md) | 🇰🇷 [한국어](./ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](./ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](./nl/API_REFERENCE.md) | 🇳🇴 [Norsk](./no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](./pt/API_REFERENCE.md) | 🇷🇴 [Română](./ro/API_REFERENCE.md) | 🇵🇱 [Polski](./pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](./sk/API_REFERENCE.md) | 🇸🇪 [Svenska](./sv/API_REFERENCE.md) | 🇵🇭 [Filipino](./phi/API_REFERENCE.md) | 🇨🇿 [Čeština](./cs/API_REFERENCE.md)
|
||||
- **ARCHITECTURE.md**: 🇺🇸 [English](../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](./es/ARCHITECTURE.md) | 🇫🇷 [Français](./fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](./it/ARCHITECTURE.md) | 🇷🇺 [Русский](./ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](./zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](./de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](./in/ARCHITECTURE.md) | 🇹🇭 [ไทย](./th/ARCHITECTURE.md) | 🇺🇦 [Українська](./uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](./ar/ARCHITECTURE.md) | 🇯🇵 [日本語](./ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](./vi/ARCHITECTURE.md) | 🇧🇬 [Български](./bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](./da/ARCHITECTURE.md) | 🇫🇮 [Suomi](./fi/ARCHITECTURE.md) | 🇮🇱 [עברית](./he/ARCHITECTURE.md) | 🇭🇺 [Magyar](./hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](./id/ARCHITECTURE.md) | 🇰🇷 [한국어](./ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](./ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](./nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](./no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](./pt/ARCHITECTURE.md) | 🇷🇴 [Română](./ro/ARCHITECTURE.md) | 🇵🇱 [Polski](./pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](./sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](./sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](./phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](./cs/ARCHITECTURE.md)
|
||||
- **CODEBASE_DOCUMENTATION.md**: 🇺🇸 [English](../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](./pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](./es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](./fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](./it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](./ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](./zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](./de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](./in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](./th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](./uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](./ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](./ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](./vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](./bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](./da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](./fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](./he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](./hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](./id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](./ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](./ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](./nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](./no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](./pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](./ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](./pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](./sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](./sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](./phi/CODEBASE_DOCUMENTATION.md) | 🇨🇿 [Čeština](./cs/CODEBASE_DOCUMENTATION.md)
|
||||
- **FEATURES.md**: 🇺🇸 [English](../FEATURES.md) | 🇧🇷 [Português (Brasil)](./pt-BR/FEATURES.md) | 🇪🇸 [Español](./es/FEATURES.md) | 🇫🇷 [Français](./fr/FEATURES.md) | 🇮🇹 [Italiano](./it/FEATURES.md) | 🇷🇺 [Русский](./ru/FEATURES.md) | 🇨🇳 [中文 (简体)](./zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](./de/FEATURES.md) | 🇮🇳 [हिन्दी](./in/FEATURES.md) | 🇹🇭 [ไทย](./th/FEATURES.md) | 🇺🇦 [Українська](./uk-UA/FEATURES.md) | 🇸🇦 [العربية](./ar/FEATURES.md) | 🇯🇵 [日本語](./ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](./vi/FEATURES.md) | 🇧🇬 [Български](./bg/FEATURES.md) | 🇩🇰 [Dansk](./da/FEATURES.md) | 🇫🇮 [Suomi](./fi/FEATURES.md) | 🇮🇱 [עברית](./he/FEATURES.md) | 🇭🇺 [Magyar](./hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](./id/FEATURES.md) | 🇰🇷 [한국어](./ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](./ms/FEATURES.md) | 🇳🇱 [Nederlands](./nl/FEATURES.md) | 🇳🇴 [Norsk](./no/FEATURES.md) | 🇵🇹 [Português (Portugal)](./pt/FEATURES.md) | 🇷🇴 [Română](./ro/FEATURES.md) | 🇵🇱 [Polski](./pl/FEATURES.md) | 🇸🇰 [Slovenčina](./sk/FEATURES.md) | 🇸🇪 [Svenska](./sv/FEATURES.md) | 🇵🇭 [Filipino](./phi/FEATURES.md) | 🇨🇿 [Čeština](./cs/FEATURES.md)
|
||||
- **TROUBLESHOOTING.md**: 🇺🇸 [English](../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](./pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](./es/TROUBLESHOOTING.md) | 🇫🇷 [Français](./fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](./it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](./ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](./zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](./de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](./in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](./th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](./uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](./ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](./ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](./vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](./bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](./da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](./fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](./he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](./hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](./id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](./ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](./ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](./nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](./no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](./pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](./ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](./pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](./sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](./sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](./phi/TROUBLESHOOTING.md) | 🇨🇿 [Čeština](./cs/TROUBLESHOOTING.md)
|
||||
- **USER_GUIDE.md**: 🇺🇸 [English](../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](./es/USER_GUIDE.md) | 🇫🇷 [Français](./fr/USER_GUIDE.md) | 🇮🇹 [Italiano](./it/USER_GUIDE.md) | 🇷🇺 [Русский](./ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](./zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](./de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](./in/USER_GUIDE.md) | 🇹🇭 [ไทย](./th/USER_GUIDE.md) | 🇺🇦 [Українська](./uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](./ar/USER_GUIDE.md) | 🇯🇵 [日本語](./ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](./vi/USER_GUIDE.md) | 🇧🇬 [Български](./bg/USER_GUIDE.md) | 🇩🇰 [Dansk](./da/USER_GUIDE.md) | 🇫🇮 [Suomi](./fi/USER_GUIDE.md) | 🇮🇱 [עברית](./he/USER_GUIDE.md) | 🇭🇺 [Magyar](./hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](./id/USER_GUIDE.md) | 🇰🇷 [한국어](./ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](./ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](./nl/USER_GUIDE.md) | 🇳🇴 [Norsk](./no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](./pt/USER_GUIDE.md) | 🇷🇴 [Română](./ro/USER_GUIDE.md) | 🇵🇱 [Polski](./pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](./sk/USER_GUIDE.md) | 🇸🇪 [Svenska](./sv/USER_GUIDE.md) | 🇵🇭 [Filipino](./phi/USER_GUIDE.md) | 🇨🇿 [Čeština](./cs/USER_GUIDE.md)
|
||||
- **VM_DEPLOYMENT_GUIDE.md**: 🇺🇸 [English](../VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](./pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](./es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](./fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](./it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](./ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](./zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](./de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](./in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](./th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](./uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](./ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](./ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](./vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](./bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](./da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](./fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](./he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](./hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](./id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](./ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](./ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](./nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](./no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](./pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](./ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](./pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](./sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](./sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](./phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](./cs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
Generated on 2026-02-26.
|
||||
Generated on 2026-03-19.
|
||||
|
||||
200
docs/i18n/ar/A2A-SERVER.md
Normal file
200
docs/i18n/ar/A2A-SERVER.md
Normal file
@@ -0,0 +1,200 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/A2A-SERVER.md) · 🇪🇸 [es](../es/A2A-SERVER.md) · 🇫🇷 [fr](../fr/A2A-SERVER.md) · 🇩🇪 [de](../de/A2A-SERVER.md) · 🇮🇹 [it](../it/A2A-SERVER.md) · 🇷🇺 [ru](../ru/A2A-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/A2A-SERVER.md) · 🇯🇵 [ja](../ja/A2A-SERVER.md) · 🇰🇷 [ko](../ko/A2A-SERVER.md) · 🇸🇦 [ar](../ar/A2A-SERVER.md) · 🇮🇳 [in](../in/A2A-SERVER.md) · 🇹🇭 [th](../th/A2A-SERVER.md) · 🇻🇳 [vi](../vi/A2A-SERVER.md) · 🇮🇩 [id](../id/A2A-SERVER.md) · 🇲🇾 [ms](../ms/A2A-SERVER.md) · 🇳🇱 [nl](../nl/A2A-SERVER.md) · 🇵🇱 [pl](../pl/A2A-SERVER.md) · 🇸🇪 [sv](../sv/A2A-SERVER.md) · 🇳🇴 [no](../no/A2A-SERVER.md) · 🇩🇰 [da](../da/A2A-SERVER.md) · 🇫🇮 [fi](../fi/A2A-SERVER.md) · 🇵🇹 [pt](../pt/A2A-SERVER.md) · 🇷🇴 [ro](../ro/A2A-SERVER.md) · 🇭🇺 [hu](../hu/A2A-SERVER.md) · 🇧🇬 [bg](../bg/A2A-SERVER.md) · 🇸🇰 [sk](../sk/A2A-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/A2A-SERVER.md) · 🇮🇱 [he](../he/A2A-SERVER.md) · 🇵🇭 [phi](../phi/A2A-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute A2A Server Documentation
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
|
||||
## Agent Discovery
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
|
||||
---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a hello world in Python"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `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 '{
|
||||
"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":"..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"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"}}'
|
||||
```
|
||||
|
||||
### `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"}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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. |
|
||||
|
||||
---
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
---
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
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"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
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",
|
||||
},
|
||||
body: 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);
|
||||
```
|
||||
@@ -1,12 +1,16 @@
|
||||
# مرجع واجهة برمجة التطبيقات
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md)
|
||||
|
||||
مرجع كامل لجميع نقاط نهاية OmniRoute API.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/API_REFERENCE.md) · 🇪🇸 [es](../es/API_REFERENCE.md) · 🇫🇷 [fr](../fr/API_REFERENCE.md) · 🇩🇪 [de](../de/API_REFERENCE.md) · 🇮🇹 [it](../it/API_REFERENCE.md) · 🇷🇺 [ru](../ru/API_REFERENCE.md) · 🇨🇳 [zh-CN](../zh-CN/API_REFERENCE.md) · 🇯🇵 [ja](../ja/API_REFERENCE.md) · 🇰🇷 [ko](../ko/API_REFERENCE.md) · 🇸🇦 [ar](../ar/API_REFERENCE.md) · 🇮🇳 [in](../in/API_REFERENCE.md) · 🇹🇭 [th](../th/API_REFERENCE.md) · 🇻🇳 [vi](../vi/API_REFERENCE.md) · 🇮🇩 [id](../id/API_REFERENCE.md) · 🇲🇾 [ms](../ms/API_REFERENCE.md) · 🇳🇱 [nl](../nl/API_REFERENCE.md) · 🇵🇱 [pl](../pl/API_REFERENCE.md) · 🇸🇪 [sv](../sv/API_REFERENCE.md) · 🇳🇴 [no](../no/API_REFERENCE.md) · 🇩🇰 [da](../da/API_REFERENCE.md) · 🇫🇮 [fi](../fi/API_REFERENCE.md) · 🇵🇹 [pt](../pt/API_REFERENCE.md) · 🇷🇴 [ro](../ro/API_REFERENCE.md) · 🇭🇺 [hu](../hu/API_REFERENCE.md) · 🇧🇬 [bg](../bg/API_REFERENCE.md) · 🇸🇰 [sk](../sk/API_REFERENCE.md) · 🇺🇦 [uk-UA](../uk-UA/API_REFERENCE.md) · 🇮🇱 [he](../he/API_REFERENCE.md) · 🇵🇭 [phi](../phi/API_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
## جدول المحتويات
|
||||
# API Reference
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md)
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
@@ -20,7 +24,7 @@
|
||||
|
||||
---
|
||||
|
||||
## إكمالات الدردشة
|
||||
## Chat Completions
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
@@ -36,21 +40,21 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
### رؤوس مخصصة
|
||||
### Custom Headers
|
||||
|
||||
| رأس | الاتجاه | الوصف |
|
||||
| ------------------------ | ------- | ------------------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | طلب | اضبط على `true` لتجاوز ذاكرة التخزين المؤقت |
|
||||
| `X-OmniRoute-Progress` | طلب | اضبط على `true` لأحداث التقدم |
|
||||
| `Idempotency-Key` | طلب | مفتاح Dedup (نافذة 5 ثواني) |
|
||||
| `X-Request-Id` | طلب | مفتاح إلغاء الحذف البديل |
|
||||
| `X-OmniRoute-Cache` | الرد | `HIT` أو `MISS` (غير متدفق) |
|
||||
| `X-OmniRoute-Idempotent` | الرد | `true` إذا تم إلغاء التكرار |
|
||||
| `X-OmniRoute-Progress` | الرد | `enabled` إذا تم تتبع التقدم على |
|
||||
| Header | Direction | Description |
|
||||
| ------------------------ | --------- | --------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
|
||||
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
|
||||
| `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 |
|
||||
|
||||
---
|
||||
|
||||
## التضمينات
|
||||
## Embeddings
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
@@ -63,7 +67,7 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
مقدمو الخدمة المتاحون: Nebius، وOpenAI، وMistral، وTogether AI، وFireworks، وNVIDIA.
|
||||
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
@@ -72,7 +76,7 @@ GET /v1/embeddings
|
||||
|
||||
---
|
||||
|
||||
## توليد الصور
|
||||
## Image Generation
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
@@ -86,7 +90,7 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
الموفرون المتاحون: OpenAI (DALL-E)، xAI (Grok Image)، Together AI (FLUX)، Fireworks AI.
|
||||
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
@@ -95,7 +99,7 @@ GET /v1/images/generations
|
||||
|
||||
---
|
||||
|
||||
## قائمة النماذج
|
||||
## List Models
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
@@ -106,22 +110,22 @@ Authorization: Bearer your-api-key
|
||||
|
||||
---
|
||||
|
||||
## نقاط نهاية التوافق
|
||||
## Compatibility Endpoints
|
||||
|
||||
| الطريقة | المسار | تنسيق |
|
||||
| -------- | --------------------------- | --------------------- |
|
||||
| مشاركة | `/v1/chat/completions` | أوبن آي |
|
||||
| مشاركة | `/v1/messages` | انثروبي |
|
||||
| مشاركة | `/v1/responses` | ردود OpenAI |
|
||||
| مشاركة | `/v1/embeddings` | أوبن آي |
|
||||
| مشاركة | `/v1/images/generations` | أوبن آي |
|
||||
| احصل على | `/v1/models` | أوبن آي |
|
||||
| مشاركة | `/v1/messages/count_tokens` | انثروبي |
|
||||
| احصل على | `/v1beta/models` | الجوزاء |
|
||||
| مشاركة | `/v1beta/models/{...path}` | الجوزاء توليد المحتوى |
|
||||
| مشاركة | `/v1/api/chat` | أولاما |
|
||||
| Method | Path | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Anthropic |
|
||||
| POST | `/v1/responses` | OpenAI Responses |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| GET | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Anthropic |
|
||||
| GET | `/v1beta/models` | Gemini |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
|
||||
### مسارات موفر مخصصة
|
||||
### Dedicated Provider Routes
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
@@ -129,11 +133,11 @@ POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
تتم إضافة بادئة الموفر تلقائيًا في حالة فقدانها. تُرجع النماذج غير المتطابقة `400`.
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
---
|
||||
|
||||
## ذاكرة التخزين المؤقت الدلالية
|
||||
## Semantic Cache
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
@@ -143,7 +147,7 @@ GET /api/cache
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
مثال الاستجابة:
|
||||
Response example:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -162,154 +166,164 @@ DELETE /api/cache
|
||||
|
||||
---
|
||||
|
||||
## لوحة القيادة والإدارة
|
||||
## Dashboard & Management
|
||||
|
||||
### المصادقة
|
||||
### Authentication
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------------- | -------------- | ------------------------ |
|
||||
| `/api/auth/login` | مشاركة | تسجيل الدخول |
|
||||
| `/api/auth/logout` | مشاركة | تسجيل الخروج |
|
||||
| `/api/settings/require-login` | الحصول على/وضع | تبديل تسجيل الدخول مطلوب |
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------------- | ------- | --------------------- |
|
||||
| `/api/auth/login` | POST | Login |
|
||||
| `/api/auth/logout` | POST | Logout |
|
||||
| `/api/settings/require-login` | GET/PUT | Toggle login required |
|
||||
|
||||
### إدارة مقدمي الخدمة
|
||||
### Provider Management
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------- | ------------------ | --------------------------- |
|
||||
| `/api/providers` | الحصول على/النشر | قائمة / إنشاء مقدمي الخدمات |
|
||||
| `/api/providers/[id]` | الحصول على/وضع/حذف | إدارة مزود |
|
||||
| `/api/providers/[id]/test` | مشاركة | اختبار اتصال الموفر |
|
||||
| `/api/providers/[id]/models` | احصل على | قائمة نماذج المزود |
|
||||
| `/api/providers/validate` | مشاركة | التحقق من صحة تكوين الموفر |
|
||||
| `/api/provider-nodes*` | متنوع | إدارة عقدة الموفر |
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | نماذج مخصصة |
|
||||
| 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 |
|
||||
|
||||
### تدفقات OAuth
|
||||
### OAuth Flows
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------------- | ------- | ------------------------ |
|
||||
| `/api/oauth/[provider]/[action]` | متنوع | OAuth الخاص بموفر الخدمة |
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------------- | ------- | ----------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
|
||||
|
||||
### التوجيه والتكوين
|
||||
### Routing & Config
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------- | ---------------- | --------------------------------- |
|
||||
| `/api/models/alias` | الحصول على/النشر | الأسماء المستعارة للنموذج |
|
||||
| `/api/models/catalog` | احصل على | جميع الموديلات حسب المزود + النوع |
|
||||
| `/api/combos*` | متنوع | إدارة التحرير والسرد |
|
||||
| `/api/keys*` | متنوع | إدارة مفاتيح API |
|
||||
| `/api/pricing` | احصل على | التسعير النموذجي |
|
||||
| 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 |
|
||||
|
||||
### الاستخدام والتحليلات
|
||||
### Usage & Analytics
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | --------------------- |
|
||||
| `/api/usage/history` | احصل على | تاريخ الاستخدام |
|
||||
| `/api/usage/logs` | احصل على | سجلات الاستخدام |
|
||||
| `/api/usage/request-logs` | احصل على | سجلات على مستوى الطلب |
|
||||
| `/api/usage/[connectionId]` | احصل على | الاستخدام لكل اتصال |
|
||||
| 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 |
|
||||
|
||||
### الإعدادات
|
||||
### Settings
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------------- | -------------- | ----------------------------------------------- |
|
||||
| `/api/settings` | الحصول على/وضع | الإعدادات العامة |
|
||||
| `/api/settings/proxy` | الحصول على/وضع | تكوين وكيل الشبكة |
|
||||
| `/api/settings/proxy/test` | مشاركة | اختبار اتصال الوكيل |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | القائمة المسموح بها/القائمة المحظورة لعناوين IP |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | الميزانية الرمزية المنطقية |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | موجه النظام العالمي |
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------------- | ------- | ---------------------- |
|
||||
| `/api/settings` | GET/PUT | 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 |
|
||||
|
||||
### المراقبة
|
||||
### Monitoring
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------------------ | -------------- | ----------------------------------- |
|
||||
| `/api/sessions` | احصل على | تتبع الجلسة النشطة |
|
||||
| `/api/rate-limits` | احصل على | حدود المعدل لكل حساب |
|
||||
| `/api/monitoring/health` | احصل على | فحص الصحة |
|
||||
| `/api/cache` | الحصول على/حذف | إحصائيات ذاكرة التخزين المؤقت / مسح |
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------ | ---------- | ----------------------- |
|
||||
| `/api/sessions` | GET | Active session tracking |
|
||||
| `/api/rate-limits` | GET | Per-account rate limits |
|
||||
| `/api/monitoring/health` | GET | Health check |
|
||||
| `/api/cache` | GET/DELETE | Cache stats / clear |
|
||||
|
||||
### النسخ الاحتياطي والتصدير/الاستيراد
|
||||
### Backup & Export/Import
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | -------------------------------------------------- |
|
||||
| `/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 |
|
||||
| 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
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------- | ------- | ------------------------ |
|
||||
| `/api/sync/cloud` | متنوع | عمليات المزامنة السحابية |
|
||||
| `/api/sync/initialize` | مشاركة | تهيئة المزامنة |
|
||||
| `/api/cloud/*` | متنوع | إدارة السحابة |
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------- | ------- | --------------------- |
|
||||
| `/api/sync/cloud` | Various | Cloud sync operations |
|
||||
| `/api/sync/initialize` | POST | Initialize sync |
|
||||
| `/api/cloud/*` | Various | Cloud management |
|
||||
|
||||
### أدوات سطر الأوامر
|
||||
### CLI Tools
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ---------------------------------- | -------- | ------------------- |
|
||||
| `/api/cli-tools/claude-settings` | احصل على | حالة كلود CLI |
|
||||
| `/api/cli-tools/codex-settings` | احصل على | حالة Codex CLI |
|
||||
| `/api/cli-tools/droid-settings` | احصل على | حالة Droid CLI |
|
||||
| `/api/cli-tools/openclaw-settings` | احصل على | حالة OpenClaw CLI |
|
||||
| `/api/cli-tools/runtime/[toolId]` | احصل على | وقت تشغيل CLI العام |
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------------------- | ------ | ------------------- |
|
||||
| `/api/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 |
|
||||
|
||||
تتضمن استجابات واجهة سطر الأوامر: `installed`، `runnable`، `command`، `commandPath`، `runtimeMode`، `reason`.
|
||||
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### المرونة وحدود الأسعار
|
||||
### ACP Agents
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ----------------------- | -------------- | ------------------------------------ |
|
||||
| `/api/resilience` | الحصول على/وضع | الحصول على/تحديث ملفات تعريف المرونة |
|
||||
| `/api/resilience/reset` | مشاركة | إعادة ضبط قواطع الدائرة |
|
||||
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
|
||||
| `/api/rate-limit` | احصل على | تكوين حد المعدل العالمي |
|
||||
| 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).
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| ------------ | ---------------- | ------------------------------------- |
|
||||
| `/api/evals` | الحصول على/النشر | قائمة مجموعات التقييم / تشغيل التقييم |
|
||||
### Resilience & Rate Limits
|
||||
|
||||
### السياسات
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------- | ------- | ------------------------------- |
|
||||
| `/api/resilience` | GET/PUT | 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/policies` | الحصول على/نشر/حذف | إدارة سياسات التوجيه |
|
||||
### Evals
|
||||
|
||||
###الامتثال
|
||||
| Endpoint | Method | Description |
|
||||
| ------------ | -------- | --------------------------------- |
|
||||
| `/api/evals` | GET/POST | List eval suites / run evaluation |
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------------------- | -------- | ---------------------------- |
|
||||
| `/api/compliance/audit-log` | احصل على | سجل تدقيق الامتثال (آخر رقم) |
|
||||
### Policies
|
||||
|
||||
### v1beta (متوافق مع الجوزاء)
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| -------------------------- | -------- | -------------------------------------- |
|
||||
| `/v1beta/models` | احصل على | قائمة النماذج بصيغة الجوزاء |
|
||||
| `/v1beta/models/{...path}` | مشاركة | الجوزاء `generateContent` نقطة النهاية |
|
||||
### Compliance
|
||||
|
||||
تعكس نقاط النهاية هذه تنسيق Gemini API للعملاء الذين يتوقعون توافق Gemini SDK الأصلي.
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
|
||||
|
||||
### واجهات برمجة التطبيقات الداخلية / النظام
|
||||
### v1beta (Gemini-Compatible)
|
||||
|
||||
| نقطة النهاية | الطريقة | الوصف |
|
||||
| --------------- | -------- | -------------------------------------------------- |
|
||||
| `/api/init` | احصل على | فحص تهيئة التطبيق (يستخدم عند التشغيل لأول مرة) |
|
||||
| `/api/tags` | احصل على | علامات النماذج المتوافقة مع Ollama (لعملاء Ollama) |
|
||||
| `/api/restart` | مشاركة | تشغيل إعادة تشغيل الخادم الرشيقة |
|
||||
| `/api/shutdown` | مشاركة | تشغيل إيقاف تشغيل الخادم بشكل رشيق |
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | --------------------------------- |
|
||||
| `/v1beta/models` | GET | List models in Gemini format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
|
||||
|
||||
> **ملاحظة:** يتم استخدام نقاط النهاية هذه داخليًا بواسطة النظام أو للتوافق مع عميل Ollama. لا يتم استدعاؤها عادة من قبل المستخدمين النهائيين.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## النسخ الصوتي
|
||||
## Audio Transcription
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
@@ -317,9 +331,9 @@ Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
قم بنسخ الملفات الصوتية باستخدام Deepgram أو AssemblyAI.
|
||||
Transcribe audio files using Deepgram or AssemblyAI.
|
||||
|
||||
**الطلب:**
|
||||
**Request:**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
@@ -328,7 +342,7 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
**الرد:**
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -339,15 +353,15 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
}
|
||||
```
|
||||
|
||||
**الموفرون المدعمون:** `deepgram/nova-3`، `assemblyai/best`.
|
||||
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**التنسيقات المدعومة:** `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.
|
||||
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
## التوافق مع أولاما
|
||||
## Ollama Compatibility
|
||||
|
||||
بالنسبة للعملاء الذين يستخدمون تنسيق واجهة برمجة تطبيقات Olma:
|
||||
For clients that use Ollama's API format:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
@@ -357,18 +371,18 @@ POST /v1/api/chat
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
تتم ترجمة الطلبات تلقائيًا بين تنسيقات Ollama والتنسيقات الداخلية.
|
||||
Requests are automatically translated between Ollama and internal formats.
|
||||
|
||||
---
|
||||
|
||||
## القياس عن بعد
|
||||
## Telemetry
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**الرد:**
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -381,7 +395,7 @@ GET /api/telemetry/summary
|
||||
|
||||
---
|
||||
|
||||
## الميزانية
|
||||
## Budget
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
@@ -400,7 +414,7 @@ Content-Type: application/json
|
||||
|
||||
---
|
||||
|
||||
## توفر النموذج
|
||||
## Model Availability
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
@@ -417,25 +431,25 @@ Content-Type: application/json
|
||||
|
||||
---
|
||||
|
||||
## معالجة الطلب
|
||||
## Request Processing
|
||||
|
||||
1. يرسل العميل طلبًا إلى `/v1/*`
|
||||
2. يستدعي معالج المسار `handleChat`، `handleEmbedding`، `handleAudioTranscription`، أو `handleImageGeneration`
|
||||
3. تم حل النموذج (المزود/النموذج المباشر أو الاسم المستعار/السرد)
|
||||
4. تم تحديد بيانات الاعتماد من قاعدة البيانات المحلية مع تصفية توفر الحساب
|
||||
5. للدردشة: `handleChatCore` — اكتشاف التنسيق، والترجمة، والتحقق من ذاكرة التخزين المؤقت، والتحقق من عدم الكفاءة
|
||||
6. يقوم منفذ الموفر بإرسال طلب المنبع
|
||||
7. تتم ترجمة الاستجابة مرة أخرى إلى تنسيق العميل (الدردشة) أو إعادتها كما هي (التضمينات/الصور/الصوت)
|
||||
8. تم تسجيل الاستخدام/التسجيل
|
||||
9. يتم تطبيق الإجراء الاحتياطي على الأخطاء وفقًا لقواعد التحرير والسرد
|
||||
1. Client sends request to `/v1/*`
|
||||
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
|
||||
3. Model is resolved (direct provider/model or alias/combo)
|
||||
4. Credentials selected from local DB with account availability filtering
|
||||
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
|
||||
6. Provider executor sends upstream request
|
||||
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
|
||||
8. Usage/logging recorded
|
||||
9. Fallback applies on errors according to combo rules
|
||||
|
||||
مرجع البنية الكاملة: [link](ARCHITECTURE.md)
|
||||
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## المصادقة
|
||||
## Authentication
|
||||
|
||||
- تستخدم مسارات لوحة المعلومات (`/dashboard/*`) ملف تعريف الارتباط `auth_token`
|
||||
- يستخدم تسجيل الدخول تجزئة كلمة المرور المحفوظة؛ الرجوع إلى `INITIAL_PASSWORD`
|
||||
- `requireLogin` قابل للتبديل عبر `/api/settings/require-login`
|
||||
- تتطلب مسارات `/v1/*` بشكل اختياري مفتاح Bearer API عندما `REQUIRE_API_KEY=true`
|
||||
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
|
||||
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
|
||||
- `requireLogin` toggleable via `/api/settings/require-login`
|
||||
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
|
||||
|
||||
@@ -1,71 +1,75 @@
|
||||
# العمارة OmniRoute
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/ARCHITECTURE.md) · 🇪🇸 [es](../es/ARCHITECTURE.md) · 🇫🇷 [fr](../fr/ARCHITECTURE.md) · 🇩🇪 [de](../de/ARCHITECTURE.md) · 🇮🇹 [it](../it/ARCHITECTURE.md) · 🇷🇺 [ru](../ru/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../zh-CN/ARCHITECTURE.md) · 🇯🇵 [ja](../ja/ARCHITECTURE.md) · 🇰🇷 [ko](../ko/ARCHITECTURE.md) · 🇸🇦 [ar](../ar/ARCHITECTURE.md) · 🇮🇳 [in](../in/ARCHITECTURE.md) · 🇹🇭 [th](../th/ARCHITECTURE.md) · 🇻🇳 [vi](../vi/ARCHITECTURE.md) · 🇮🇩 [id](../id/ARCHITECTURE.md) · 🇲🇾 [ms](../ms/ARCHITECTURE.md) · 🇳🇱 [nl](../nl/ARCHITECTURE.md) · 🇵🇱 [pl](../pl/ARCHITECTURE.md) · 🇸🇪 [sv](../sv/ARCHITECTURE.md) · 🇳🇴 [no](../no/ARCHITECTURE.md) · 🇩🇰 [da](../da/ARCHITECTURE.md) · 🇫🇮 [fi](../fi/ARCHITECTURE.md) · 🇵🇹 [pt](../pt/ARCHITECTURE.md) · 🇷🇴 [ro](../ro/ARCHITECTURE.md) · 🇭🇺 [hu](../hu/ARCHITECTURE.md) · 🇧🇬 [bg](../bg/ARCHITECTURE.md) · 🇸🇰 [sk](../sk/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../uk-UA/ARCHITECTURE.md) · 🇮🇱 [he](../he/ARCHITECTURE.md) · 🇵🇭 [phi](../phi/ARCHITECTURE.md)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
||||
---
|
||||
|
||||
_آخر تحديث: 2026-02-18_
|
||||
# OmniRoute Architecture
|
||||
|
||||
## ملخص تنفيذي
|
||||
🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md)
|
||||
|
||||
OmniRoute عبارة عن بوابة توجيه محلية تعمل بالذكاء الاصطناعي ولوحة معلومات مبنية على Next.js.
|
||||
فهو يوفر نقطة نهاية واحدة متوافقة مع OpenAI (`/v1/*`) ويوجه حركة المرور عبر العديد من موفري الخدمات الأولية مع الترجمة والاحتياط وتحديث الرمز المميز وتتبع الاستخدام.
|
||||
_Last updated: 2026-03-04_
|
||||
|
||||
القدرات الأساسية:
|
||||
## Executive Summary
|
||||
|
||||
- سطح API متوافق مع OpenAI لـ CLI/الأدوات (28 مزودًا)
|
||||
- ترجمة الطلب/الاستجابة عبر تنسيقات الموفر
|
||||
- نموذج احتياطي التحرير والسرد (تسلسل متعدد النماذج)
|
||||
- احتياطي على مستوى الحساب (حسابات متعددة لكل مزود)
|
||||
- إدارة اتصال موفر OAuth + API-key
|
||||
- إنشاء التضمين عبر `/v1/embeddings` (6 موفري خدمات، 9 نماذج)
|
||||
- إنشاء الصور عبر `/v1/images/generations` (4 مقدمي خدمات، 9 نماذج)
|
||||
- فكر في تحليل العلامات (`<think>...</think>`) لنماذج الاستدلال
|
||||
- تعقيم الاستجابة للتوافق الصارم مع OpenAI SDK
|
||||
- تطبيع الدور (المطور → النظام، النظام → المستخدم) للتوافق بين الموفرين
|
||||
- تحويل الإخراج المنظم (json_schema → Gemini ResponseSchema)
|
||||
- الثبات المحلي لمقدمي الخدمات والمفاتيح والأسماء المستعارة والمجموعات والإعدادات والتسعير
|
||||
- تتبع الاستخدام/التكلفة وتسجيل الطلب
|
||||
- مزامنة سحابية اختيارية لمزامنة الأجهزة/الحالة المتعددة
|
||||
- القائمة المسموح بها/القائمة المحظورة لـ IP للتحكم في الوصول إلى واجهة برمجة التطبيقات
|
||||
- التفكير في إدارة الميزانية (العبور / التلقائي / المخصص / التكيفي)
|
||||
- الحقن الفوري للنظام العالمي
|
||||
- تتبع الجلسة وأخذ البصمات
|
||||
- تحديد المعدل المحسن لكل حساب مع الملفات الشخصية الخاصة بالمزود
|
||||
- نمط قاطع الدائرة لمرونة المزود
|
||||
- حماية القطيع ضد الرعد مع قفل Mutex
|
||||
- ذاكرة التخزين المؤقت لإلغاء البيانات المكررة للطلب المستندة إلى التوقيع
|
||||
- طبقة المجال: توفر النموذج، وقواعد التكلفة، والسياسة الاحتياطية، وسياسة الإغلاق
|
||||
- استمرارية حالة المجال (ذاكرة التخزين المؤقت للكتابة في SQLite للاحتياطيات والميزانيات وعمليات الإغلاق وقواطع الدائرة)
|
||||
- محرك السياسة لتقييم الطلب المركزي (التأمين → الميزانية → الاحتياطي)
|
||||
- طلب القياس عن بعد مع تجميع الكمون p50/p95/p99
|
||||
- معرف الارتباط (X-Request-Id) للتتبع الشامل
|
||||
- تسجيل تدقيق الامتثال مع إلغاء الاشتراك لكل مفتاح API
|
||||
- إطار تقييمي لضمان جودة LLM
|
||||
- لوحة تحكم واجهة المستخدم المرنة مع حالة قاطع الدائرة في الوقت الفعلي
|
||||
- موفرو OAuth المعياريون (12 وحدة فردية ضمن `src/lib/oauth/providers/`)
|
||||
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:
|
||||
|
||||
- تقوم مسارات تطبيق Next.js ضمن `src/app/api/*` بتنفيذ كل من واجهات برمجة تطبيقات لوحة المعلومات وواجهات برمجة تطبيقات التوافق
|
||||
- نواة توجيه/SSE مشتركة في `src/sse/*` + `open-sse/*` تتعامل مع تنفيذ الموفر والترجمة والتدفق والرجوع والاستخدام
|
||||
- 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
|
||||
|
||||
- وقت تشغيل البوابة المحلية
|
||||
- واجهات برمجة التطبيقات لإدارة لوحة المعلومات
|
||||
- مصادقة الموفر وتحديث الرمز المميز
|
||||
- طلب الترجمة وتدفق SSE
|
||||
- الحالة المحلية + استمرارية الاستخدام
|
||||
- تنسيق مزامنة سحابية اختيارية
|
||||
## Scope and Boundaries
|
||||
|
||||
### خارج النطاق
|
||||
### In Scope
|
||||
|
||||
- تنفيذ الخدمة السحابية خلف `NEXT_PUBLIC_CLOUD_URL`
|
||||
- مزود مستوى جيش تحرير السودان/مستوى التحكم خارج العملية المحلية
|
||||
- ثنائيات CLI الخارجية نفسها (Claude CLI، Codex CLI، وما إلى ذلك)
|
||||
- Local gateway runtime
|
||||
- Dashboard management APIs
|
||||
- Provider authentication and token refresh
|
||||
- Request translation and SSE streaming
|
||||
- Local state + usage persistence
|
||||
- Optional cloud sync orchestration
|
||||
|
||||
## سياق النظام عالي المستوى
|
||||
### Out of Scope
|
||||
|
||||
- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Provider SLA/control plane outside local process
|
||||
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
|
||||
|
||||
## High-Level System Context
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -81,8 +85,8 @@ flowchart LR
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(db.json)]
|
||||
UDB[(usage.json + log.txt)]
|
||||
DB[(storage.sqlite)]
|
||||
UDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
@@ -113,151 +117,152 @@ flowchart LR
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## مكونات وقت التشغيل الأساسية
|
||||
## Core Runtime Components
|
||||
|
||||
## 1) واجهة برمجة التطبيقات وطبقة التوجيه (مسارات تطبيق Next.js)
|
||||
## 1) API and Routing Layer (Next.js App Routes)
|
||||
|
||||
الدلائل الرئيسية:
|
||||
Main directories:
|
||||
|
||||
- `src/app/api/v1/*` و`src/app/api/v1beta/*` لواجهات برمجة تطبيقات التوافق
|
||||
- `src/app/api/*` لواجهات برمجة التطبيقات للإدارة/التكوين
|
||||
- تتم إعادة الكتابة التالية في الخريطة `next.config.mjs` من `/v1/*` إلى `/api/v1/*`
|
||||
- `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/*`
|
||||
|
||||
طرق التوافق الهامة:
|
||||
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` — يتضمن نماذج مخصصة مع `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/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/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — دردشة مخصصة لكل مزود
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — عمليات التضمين المخصصة لكل مزود
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — صور مخصصة لكل مزود
|
||||
- `src/app/api/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/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
مجالات الإدارة:
|
||||
Management domains:
|
||||
|
||||
- المصادقة/الإعدادات: `src/app/api/auth/*`، `src/app/api/settings/*`
|
||||
- مقدمو الخدمة/الاتصالات: `src/app/api/providers*`
|
||||
- عقد الموفر: `src/app/api/provider-nodes*`
|
||||
- النماذج المخصصة: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- كتالوج النماذج: `src/app/api/models/catalog` (GET)
|
||||
- تكوين الوكيل: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- 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)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- المفاتيح/الأسماء المستعارة/المجموعات/التسعير: `src/app/api/keys*`، `src/app/api/models/alias`، `src/app/api/combos*`، `src/app/api/pricing`
|
||||
- الاستخدام: `src/app/api/usage/*`
|
||||
- المزامنة/السحابة: `src/app/api/sync/*`، `src/app/api/cloud/*`
|
||||
- مساعدي أدوات CLI: `src/app/api/cli-tools/*`
|
||||
- مرشح IP: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- ميزانية التفكير: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- موجه النظام: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- الجلسات: `src/app/api/sessions` (GET)
|
||||
- حدود الأسعار: `src/app/api/rate-limits` (GET)
|
||||
- المرونة: `src/app/api/resilience` (GET/PATCH) - ملفات تعريف الموفر، قاطع الدائرة، حالة حد المعدل
|
||||
- إعادة ضبط المرونة: `src/app/api/resilience/reset` (POST) — إعادة ضبط الفواصل + فترات التهدئة
|
||||
- إحصائيات ذاكرة التخزين المؤقت: `src/app/api/cache/stats` (الحصول على/الحذف)
|
||||
- توفر النموذج: `src/app/api/models/availability` (GET/POST)
|
||||
- القياس عن بعد: `src/app/api/telemetry/summary` (GET)
|
||||
- الميزانية: `src/app/api/usage/budget` (GET/POST)
|
||||
- السلاسل الاحتياطية: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- تدقيق الامتثال: `src/app/api/compliance/audit-log` (GET)
|
||||
- التقييمات: `src/app/api/evals` (GET/POST)، `src/app/api/evals/[suiteId]` (GET)
|
||||
- السياسات: `src/app/api/policies` (GET/POST)
|
||||
- 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)
|
||||
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Policies: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + جوهر الترجمة
|
||||
## 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`
|
||||
- معرف الطلب: `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`، `iflow.ts`، `qwen.ts`، `kimi-coding.ts`، `github.ts`، `kiro.ts`، `cursor.ts`، `kilocode.ts`، `cline.ts`
|
||||
- الغلاف الرقيق: `src/lib/oauth/providers.ts` — إعادة التصدير من الوحدات الفردية
|
||||
- Registry index: `src/lib/oauth/providers/index.ts`
|
||||
- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules
|
||||
|
||||
## 3) طبقة الثبات
|
||||
## 3) Persistence Layer
|
||||
|
||||
قاعدة بيانات الحالة الأساسية:
|
||||
Primary state DB (SQLite):
|
||||
|
||||
- `src/lib/localDb.ts`
|
||||
- الملف: `${DATA_DIR}/db.json` (أو `$XDG_CONFIG_HOME/omniroute/db.json` عند التعيين، وإلا `~/.omniroute/db.json`)
|
||||
- الكيانات:providerConnections، وproviderNodes، وmodelAliases، والمجموعات، وapiKeys، والإعدادات، والتسعير، **customModels**، **proxyConfig**، **ipFilter**، **thinkingBudget**، **systemPrompt**
|
||||
- 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**
|
||||
|
||||
قاعدة بيانات الاستخدام:
|
||||
Usage persistence:
|
||||
|
||||
- `src/lib/usageDb.ts`
|
||||
- الملفات: `${DATA_DIR}/usage.json`، `${DATA_DIR}/log.txt`، `${DATA_DIR}/call_logs/`
|
||||
- يتبع نفس سياسة الدليل الأساسي مثل `localDb` (`DATA_DIR`، ثم `XDG_CONFIG_HOME/omniroute` عند التعيين)
|
||||
- مقسمة إلى وحدات فرعية مركزة: `migrations.ts`، `usageHistory.ts`، `costCalculator.ts`، `usageStats.ts`، `callLogs.ts`
|
||||
- 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
|
||||
|
||||
قاعدة بيانات حالة المجال (SQLite):
|
||||
Domain State DB (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — عمليات CRUD لحالة المجال
|
||||
- الجداول (التي تم إنشاؤها في `src/lib/db/core.ts`): `domain_fallback_chains`، `domain_budgets`، `domain_cost_history`، `domain_lockout_state`، `domain_circuit_breakers`
|
||||
- نمط ذاكرة التخزين المؤقت للكتابة: تعد الخرائط الموجودة في الذاكرة موثوقة في وقت التشغيل؛ تتم كتابة الطفرات بشكل متزامن إلى SQLite؛ تتم استعادة الحالة من قاعدة البيانات عند البداية الباردة
|
||||
- `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) المصادقة + الأسطح الأمنية
|
||||
## 4) Auth + Security Surfaces
|
||||
|
||||
- مصادقة ملف تعريف الارتباط للوحة المعلومات: `src/proxy.ts`، `src/app/api/auth/login/route.ts`
|
||||
- إنشاء/التحقق من مفتاح واجهة برمجة التطبيقات: `src/shared/utils/apiKey.ts`
|
||||
- استمرت أسرار الموفر في إدخالات `providerConnections`
|
||||
- دعم الوكيل الصادر عبر `open-sse/utils/proxyFetch.ts` (env vars) و`open-sse/utils/networkProxy.ts` (قابل للتكوين لكل موفر أو عالمي)
|
||||
- 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) المزامنة السحابية
|
||||
## 5) Cloud Sync
|
||||
|
||||
- الحرف الأول للمجدول: `src/lib/initCloudSync.ts`، `src/shared/services/initializeCloudSync.ts`
|
||||
- المهمة الدورية: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- مسار التحكم: `src/app/api/sync/cloud/route.ts`
|
||||
- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
||||
- Periodic task: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Control route: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## دورة حياة الطلب (`/v1/chat/completions`)
|
||||
## Request Lifecycle (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -304,7 +309,7 @@ sequenceDiagram
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## التحرير والسرد + التدفق الاحتياطي للحساب
|
||||
## Combo + Account Fallback Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -334,9 +339,9 @@ flowchart TD
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
يتم اتخاذ القرارات الاحتياطية بواسطة `open-sse/services/accountFallback.ts` باستخدام رموز الحالة والاستدلال على رسائل الخطأ.
|
||||
Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics.
|
||||
|
||||
## دورة حياة OAuth Onboarding وتحديث الرمز المميز
|
||||
## OAuth Onboarding and Token Refresh Lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -366,9 +371,9 @@ sequenceDiagram
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
يتم تنفيذ التحديث أثناء حركة المرور المباشرة داخل `open-sse/handlers/chatCore.ts` عبر المنفذ `refreshCredentials()`.
|
||||
Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
||||
|
||||
## دورة حياة المزامنة السحابية (تمكين / مزامنة / تعطيل)
|
||||
## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -400,9 +405,9 @@ sequenceDiagram
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
يتم تشغيل المزامنة الدورية بواسطة `CloudSyncScheduler` عند تمكين السحابة.
|
||||
Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
|
||||
|
||||
## نموذج البيانات وخريطة التخزين
|
||||
## Data Model and Storage Map
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
@@ -503,14 +508,14 @@ erDiagram
|
||||
}
|
||||
```
|
||||
|
||||
ملفات التخزين المادية:
|
||||
Physical storage files:
|
||||
|
||||
- الحالة الرئيسية: `${DATA_DIR}/db.json` (أو `$XDG_CONFIG_HOME/omniroute/db.json` عند التعيين، وإلا `~/.omniroute/db.json`)
|
||||
- إحصائيات الاستخدام: `${DATA_DIR}/usage.json`
|
||||
- خطوط سجل الطلب: `${DATA_DIR}/log.txt`
|
||||
- جلسات تصحيح أخطاء المترجم/الطلب الاختيارية: `<repo>/logs/...`
|
||||
- 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
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -522,8 +527,8 @@ flowchart LR
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(db.json)]
|
||||
UsageDB[(usage.json/log.txt)]
|
||||
MainDB[(storage.sqlite)]
|
||||
UsageDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
@@ -541,241 +546,242 @@ flowchart LR
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## تعيين الوحدة (القرار الحاسم)
|
||||
## Module Mapping (Decision-Critical)
|
||||
|
||||
### وحدات المسار وواجهة برمجة التطبيقات
|
||||
### Route and API Modules
|
||||
|
||||
- `src/app/api/v1/*`، `src/app/api/v1beta/*`: واجهات برمجة تطبيقات التوافق
|
||||
- `src/app/api/v1/providers/[provider]/*`: مسارات مخصصة لكل مزود (الدردشة والتضمين والصور)
|
||||
- `src/app/api/providers*`: موفر CRUD والتحقق من الصحة والاختبار
|
||||
- `src/app/api/provider-nodes*`: إدارة العقدة المتوافقة المخصصة
|
||||
- `src/app/api/provider-models`: إدارة النماذج المخصصة (CRUD)
|
||||
- `src/app/api/models/catalog`: واجهة برمجة تطبيقات كتالوج النموذج الكامل (جميع الأنواع مجمعة حسب الموفر)
|
||||
- `src/app/api/oauth/*`: تدفقات OAuth/رمز الجهاز
|
||||
- `src/app/api/keys*`: دورة حياة مفتاح واجهة برمجة التطبيقات المحلية
|
||||
- `src/app/api/models/alias`: إدارة الاسم المستعار
|
||||
- `src/app/api/combos*`: إدارة التحرير والسرد الاحتياطية
|
||||
- `src/app/api/pricing`: تجاوزات التسعير لحساب التكلفة
|
||||
- `src/app/api/settings/proxy`: تكوين الوكيل (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: اختبار اتصال الوكيل الصادر (POST)
|
||||
- `src/app/api/usage/*`: واجهات برمجة تطبيقات الاستخدام والسجلات
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: المزامنة السحابية والمساعدون الذين يواجهون السحابة
|
||||
- `src/app/api/cli-tools/*`: كاتب/أداة فحص تكوين CLI المحلية
|
||||
- `src/app/api/settings/ip-filter`: قائمة IP المسموح بها/القائمة المحظورة (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: تكوين ميزانية الرمز المميز (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: موجه النظام العالمي (GET/PUT)
|
||||
- `src/app/api/sessions`: قائمة الجلسة النشطة (GET)
|
||||
- `src/app/api/rate-limits`: حالة حد السعر لكل حساب (GET)
|
||||
- `src/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)
|
||||
|
||||
### التوجيه والتنفيذ الأساسي
|
||||
### Routing and Execution Core
|
||||
|
||||
- `src/sse/handlers/chat.ts`: تحليل الطلب، ومعالجة التحرير والسرد، وحلقة اختيار الحساب
|
||||
- `open-sse/handlers/chatCore.ts`: الترجمة، إرسال المنفذ، معالجة إعادة المحاولة/التحديث، إعداد الدفق
|
||||
- `open-sse/executors/*`: سلوك الشبكة والتنسيق الخاص بالموفر
|
||||
- `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
|
||||
|
||||
### سجل الترجمة ومحولات التنسيق
|
||||
### Translation Registry and Format Converters
|
||||
|
||||
- `open-sse/translator/index.ts`: تسجيل المترجم وتنسيقه
|
||||
- طلب المترجمين: `open-sse/translator/request/*`
|
||||
- مترجمو الرد: `open-sse/translator/response/*`
|
||||
- ثوابت التنسيق: `open-sse/translator/formats.ts`
|
||||
- `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`
|
||||
|
||||
### المثابرة
|
||||
### Persistence
|
||||
|
||||
- `src/lib/localDb.ts`: التكوين/الحالة المستمرة
|
||||
- `src/lib/usageDb.ts`: سجل الاستخدام وسجلات الطلبات المتجددة
|
||||
- `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
|
||||
|
||||
## تغطية منفذي الخدمة (نمط الإستراتيجية)
|
||||
## Provider Executor Coverage (Strategy Pattern)
|
||||
|
||||
كل مزود لديه منفذ متخصص يمتد `BaseExecutor` (في `open-sse/executors/base.ts`)، والذي يوفر بناء عنوان URL، وإنشاء الرأس، وإعادة المحاولة مع التراجع الأسي، وخطافات تحديث بيانات الاعتماد، وطريقة التنسيق `execute()`.
|
||||
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.
|
||||
|
||||
| المنفذ | المزود (المقدمون) | التعامل الخاص |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI، Claude، Gemini، Qwen، iFlow، OpenRouter، GLM، Kimi، MiniMax، DeepSeek، Groq، xAI، Mistral، Perplexity، Together، Fireworks، Cerebras، Cohere، NVIDIA | تكوين عنوان URL/الرأس الديناميكي لكل مزود |
|
||||
| `AntigravityExecutor` | جوجل مكافحة الجاذبية | معرفات المشروع/الجلسة المخصصة، إعادة المحاولة بعد التحليل |
|
||||
| `CodexExecutor` | OpenAI Codex | يحقن تعليمات النظام، ويفرض جهدًا منطقيًا |
|
||||
| `CursorExecutor` | بيئة تطوير متكاملة للمؤشر | بروتوكول ConnectRPC، تشفير Protobuf، طلب التوقيع عبر المجموع الاختباري |
|
||||
| `GithubExecutor` | جيثب مساعد الطيار | تحديث الرمز المميز لـ Copilot، ورؤوس محاكاة VSCode |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/كيرو | تنسيق AWS EventStream الثنائي → تحويل SSE |
|
||||
| `GeminiCLIExecutor` | الجوزاء CLI | دورة تحديث رمز OAuth المميز لـ Google |
|
||||
| Executor | Provider(s) | Special Handling |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, 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 |
|
||||
|
||||
يستخدم جميع الموفرين الآخرين (بما في ذلك العقد المتوافقة المخصصة) `DefaultExecutor`.
|
||||
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
|
||||
|
||||
## مصفوفة توافق الموفر
|
||||
## Provider Compatibility Matrix
|
||||
|
||||
| مقدم | تنسيق | مصادقة | تيار | غير دفق | تحديث الرمز المميز | واجهة برمجة تطبيقات الاستخدام |
|
||||
| ----------------------------------- | ---------------- | --------------------------- | --------------- | ------- | ------------------ | ----------------------------- |
|
||||
| كلود | كلود | مفتاح API / OAuth | ✅ | ✅ | ✅ | ⚠️ المشرف فقط |
|
||||
| الجوزاء | الجوزاء | مفتاح API / OAuth | ✅ | ✅ | ✅ | ⚠️ وحدة التحكم السحابية |
|
||||
| الجوزاء CLI | الجوزاء-cli | أووث | ✅ | ✅ | ✅ | ⚠️ وحدة التحكم السحابية |
|
||||
| مكافحة الجاذبية | ضد الجاذبية | أووث | ✅ | ✅ | ✅ | ✅ الحصة الكاملة API |
|
||||
| أوبن آي | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الدستور الغذائي | openai-responses | أووث | ✅ مجبور | ❌ | ✅ | ✅ حدود المعدل |
|
||||
| جيثب مساعد الطيار | أوبيناي | OAuth + رمز مساعد الطيار | ✅ | ✅ | ✅ | ✅ لقطات الحصص |
|
||||
| المؤشر | المؤشر | المجموع الاختباري المخصص | ✅ | ✅ | ❌ | ❌ |
|
||||
| كيرو | كيرو | AWS SSO OIDC | ✅(ايفنت ستريم) | ❌ | ✅ | ✅ حدود الاستخدام |
|
||||
| كوين | أوبيناي | أووث | ✅ | ✅ | ✅ | ⚠️ حسب الطلب |
|
||||
| اي فلو | أوبيناي | OAuth (أساسي) | ✅ | ✅ | ✅ | ⚠️ حسب الطلب |
|
||||
| اوبن راوتر | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| جي إل إم/كيمي/ميني ماكس | كلود | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| ديب سيك | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| جروك | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (جروك) | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| ميسترال | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الحيرة | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| معا منظمة العفو الدولية | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| الألعاب النارية منظمة العفو الدولية | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| المخيخ | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| كوهير | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| نفيديا نيم | أوبيناي | مفتاح واجهة برمجة التطبيقات | ✅ | ✅ | ❌ | ❌ |
|
||||
| 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 |
|
||||
| iFlow | 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
|
||||
- كلود
|
||||
- الجوزاء/الجوزاء-CLI/الظرف المضاد للجاذبية
|
||||
- كيرو
|
||||
- المؤشر
|
||||
- OpenAI chat/Responses
|
||||
- Claude
|
||||
- Gemini/Gemini-CLI/Antigravity envelope
|
||||
- Kiro
|
||||
- Cursor
|
||||
|
||||
تستخدم الترجمات **OpenAI كتنسيق مركزي** — تمر جميع التحويلات عبر OpenAI كتنسيق وسيط:
|
||||
Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
- **تطهير الاستجابة** — يزيل الحقول غير القياسية من استجابات تنسيق OpenAI (سواء المتدفقة أو غير المتدفقة) لضمان الامتثال الصارم لـ SDK
|
||||
- **تطبيع الدور** — تحويل `developer` → `system` للأهداف غير التابعة لـ OpenAI؛ يدمج `system` → `user` للنماذج التي ترفض دور النظام (GLM، ERNIE)
|
||||
- **فكر في استخراج العلامات** — يوزع كتل `<think>...</think>` من المحتوى إلى حقل `reasoning_content`
|
||||
- **الإخراج المنظم** — يحول OpenAI `response_format.json_schema` إلى `responseMimeType` + `responseSchema` الخاص بـ Gemini
|
||||
- **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
|
||||
|
||||
| نقطة النهاية | تنسيق | معالج |
|
||||
| -------------------------------------------------- | ------------------ | ------------------------------------------------------------------------- |
|
||||
| `POST /v1/chat/completions` | دردشة OpenAI | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | رسائل كلود | نفس المعالج (تم اكتشافه تلقائيًا) |
|
||||
| `POST /v1/responses` | ردود OpenAI | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | تضمينات OpenAI | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | قائمة النماذج | طريق API |
|
||||
| `POST /v1/images/generations` | صور OpenAI | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | قائمة النماذج | طريق API |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | دردشة OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/providers/{provider}/embeddings` | تضمينات OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/providers/{provider}/images/generations` | صور OpenAI | مخصص لكل مزود مع التحقق من صحة النموذج |
|
||||
| `POST /v1/messages/count_tokens` | عدد كلود توكن | طريق API |
|
||||
| `GET /v1/models` | قائمة نماذج OpenAI | مسار واجهة برمجة التطبيقات (الدردشة + التضمين + الصورة + النماذج المخصصة) |
|
||||
| `GET /api/models/catalog` | كتالوج | جميع النماذج مجمعة حسب الموفر + النوع |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | مولود برج الجوزاء | طريق API |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | تكوين الوكيل | تكوين وكيل الشبكة |
|
||||
| `POST /api/settings/proxy/test` | اتصال الوكيل | نقطة نهاية اختبار صحة الوكيل/الاتصال |
|
||||
| `GET/POST/DELETE /api/provider-models` | نماذج مخصصة | إدارة النماذج المخصصة لكل مزود |
|
||||
| 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` | Custom Models | Custom model management per provider |
|
||||
|
||||
## تجاوز المعالج
|
||||
## Bypass Handler
|
||||
|
||||
يعترض معالج التجاوز (`open-sse/utils/bypassHandler.ts`) طلبات "الرمي" المعروفة من Claude CLI - أصوات التمهيد، واستخراج العناوين، وعدد الرموز المميزة - ويعيد **استجابة زائفة** دون استهلاك الرموز المميزة للموفر الرئيسي. يتم تشغيل هذا فقط عندما يحتوي `User-Agent` على `claude-cli`.
|
||||
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
|
||||
|
||||
يوفر مسجل الطلب (`open-sse/utils/requestLogger.ts`) مسارًا لتسجيل تصحيح الأخطاء مكون من 7 مراحل، معطل افتراضيًا، وممكن عبر `ENABLE_REQUEST_LOGS=true`:
|
||||
The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
|
||||
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
|
||||
```
|
||||
|
||||
تتم كتابة الملفات إلى `<repo>/logs/<session>/` لكل جلسة طلب.
|
||||
Files are written to `<repo>/logs/<session>/` for each request session.
|
||||
|
||||
## أوضاع الفشل والمرونة
|
||||
## Failure Modes and Resilience
|
||||
|
||||
## 1) توفر الحساب/المزود
|
||||
## 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) انتهاء صلاحية الرمز المميز
|
||||
## 2) Token Expiry
|
||||
|
||||
- الفحص المسبق والتحديث مع إعادة المحاولة لموفري الخدمة القابلين للتحديث
|
||||
- 401/403 إعادة المحاولة بعد محاولة التحديث في المسار الأساسي
|
||||
- pre-check and refresh with retry for refreshable providers
|
||||
- 401/403 retry after refresh attempt in core path
|
||||
|
||||
## 3) سلامة الدفق
|
||||
## 3) Stream Safety
|
||||
|
||||
- وحدة تحكم تيار قطع الاتصال
|
||||
- دفق الترجمة مع تدفق نهاية الدفق ومعالجة `[DONE]`
|
||||
- احتياطي تقدير الاستخدام عندما تكون البيانات الوصفية لاستخدام الموفر مفقودة
|
||||
- disconnect-aware stream controller
|
||||
- translation stream with end-of-stream flush and `[DONE]` handling
|
||||
- usage estimation fallback when provider usage metadata is missing
|
||||
|
||||
## 4) تدهور المزامنة السحابية
|
||||
## 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
|
||||
|
||||
## 5) سلامة البيانات
|
||||
## 5) Data Integrity
|
||||
|
||||
- ترحيل/إصلاح شكل قاعدة البيانات للمفاتيح المفقودة
|
||||
- ضمانات إعادة تعيين JSON الفاسدة لـ localDb وuseDb
|
||||
- SQLite schema migrations and auto-upgrade hooks at startup
|
||||
- legacy JSON → SQLite migration compatibility path
|
||||
|
||||
## إمكانية الملاحظة والإشارات التشغيلية
|
||||
## Observability and Operational Signals
|
||||
|
||||
مصادر رؤية وقت التشغيل:
|
||||
Runtime visibility sources:
|
||||
|
||||
- سجلات وحدة التحكم من `src/sse/utils/logger.ts`
|
||||
- مجاميع الاستخدام لكل طلب في `usage.json`
|
||||
- سجل حالة الطلب النصي في `log.txt`
|
||||
- سجلات الطلب/الترجمة العميقة الاختيارية ضمن `logs/` عندما `ENABLE_REQUEST_LOGS=true`
|
||||
- نقاط نهاية استخدام لوحة المعلومات (`/api/usage/*`) لاستهلاك واجهة المستخدم
|
||||
- console logs from `src/sse/utils/logger.ts`
|
||||
- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- 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
|
||||
|
||||
## الحدود الحساسة للأمن
|
||||
## Security-Sensitive Boundaries
|
||||
|
||||
- سر JWT (`JWT_SECRET`) يؤمن التحقق/التوقيع على ملف تعريف الارتباط لجلسة لوحة المعلومات
|
||||
- يجب تجاوز الاحتياطي الأولي لكلمة المرور (`INITIAL_PASSWORD`، الافتراضي `123456`) في عمليات النشر الحقيقية
|
||||
- سر HMAC لمفتاح API (`API_KEY_SECRET`) يؤمن تنسيق مفتاح API المحلي الذي تم إنشاؤه
|
||||
- تظل أسرار الموفر (مفاتيح/رموز واجهة برمجة التطبيقات) موجودة في قاعدة البيانات المحلية ويجب حمايتها على مستوى نظام الملفات
|
||||
- تعتمد نقاط نهاية المزامنة السحابية على مصادقة مفتاح API + دلالات معرف الجهاز
|
||||
- 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:
|
||||
|
||||
- التطبيق/المصادقة: `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`
|
||||
- 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` و`localDb` الآن نفس سياسة الدليل الأساسي (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) مع ترحيل الملفات القديمة.
|
||||
2. يقوم `/api/v1/route.ts` بإرجاع قائمة نماذج ثابتة وهو ليس مصدر النماذج الرئيسي الذي يستخدمه `/v1/models`.
|
||||
3. يقوم مسجل الطلب بكتابة الرؤوس/النص الكامل عند تمكينه؛ التعامل مع دليل السجل على أنه حساس.
|
||||
4. يعتمد سلوك السحابة على `NEXT_PUBLIC_BASE_URL` الصحيح وإمكانية الوصول إلى نقطة نهاية السحابة.
|
||||
5. تم نشر الدليل `open-sse/` باسم `@omniroute/open-sse` **حزمة مساحة عمل npm**. يقوم كود المصدر باستيراده عبر `@omniroute/open-sse/...` (تم حله بواسطة Next.js `transpilePackages`). لا تزال مسارات الملفات في هذا المستند تستخدم اسم الدليل `open-sse/` لتحقيق الاتساق.
|
||||
6. تستخدم المخططات الموجودة في لوحة المعلومات **Recharts** (المستندة إلى SVG) لتصورات التحليلات التفاعلية التي يمكن الوصول إليها (المخططات الشريطية لاستخدام النموذج، والجداول التفصيلية للموفرين مع معدلات النجاح).
|
||||
7. تستخدم اختبارات E2E **Playwright** (`tests/e2e/`)، ويتم تشغيلها عبر `npm run test:e2e`. تستخدم اختبارات الوحدة **مشغل اختبار Node.js** (`tests/unit/`)، ويتم تشغيله عبر `npm run test:plan3`. كود المصدر ضمن `src/` هو **TypeScript** (`.ts`/`.tsx`)؛ تظل مساحة العمل `open-sse/` JavaScript (`.js`).
|
||||
8. تم تنظيم صفحة الإعدادات في 5 علامات تبويب: الأمان، التوجيه (6 إستراتيجيات عالمية: التعبئة أولاً، جولة روبن، p2c، عشوائي، الأقل استخدامًا، تحسين التكلفة)، المرونة (حدود المعدل القابلة للتحرير، قاطع الدائرة، السياسات)، الذكاء الاصطناعي (ميزانية التفكير، موجه النظام، ذاكرة التخزين المؤقت السريعة)، المتقدم (الوكيل).
|
||||
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
|
||||
|
||||
- البناء من المصدر: `npm run build`
|
||||
- إنشاء صورة Docker: `docker build -t omniroute .`
|
||||
- ابدأ الخدمة وتحقق:
|
||||
- Build from source: `npm run build`
|
||||
- Build Docker image: `docker build -t omniroute .`
|
||||
- Start service and verify:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- يجب أن يكون عنوان URL الأساسي لهدف واجهة سطر الأوامر هو `http://<host>:20128/v1` عندما يكون `PORT=20128`
|
||||
- CLI target base URL should be `http://<host>:20128/v1` when `PORT=20128`
|
||||
|
||||
67
docs/i18n/ar/AUTO-COMBO.md
Normal file
67
docs/i18n/ar/AUTO-COMBO.md
Normal file
@@ -0,0 +1,67 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/AUTO-COMBO.md) · 🇪🇸 [es](../es/AUTO-COMBO.md) · 🇫🇷 [fr](../fr/AUTO-COMBO.md) · 🇩🇪 [de](../de/AUTO-COMBO.md) · 🇮🇹 [it](../it/AUTO-COMBO.md) · 🇷🇺 [ru](../ru/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../zh-CN/AUTO-COMBO.md) · 🇯🇵 [ja](../ja/AUTO-COMBO.md) · 🇰🇷 [ko](../ko/AUTO-COMBO.md) · 🇸🇦 [ar](../ar/AUTO-COMBO.md) · 🇮🇳 [in](../in/AUTO-COMBO.md) · 🇹🇭 [th](../th/AUTO-COMBO.md) · 🇻🇳 [vi](../vi/AUTO-COMBO.md) · 🇮🇩 [id](../id/AUTO-COMBO.md) · 🇲🇾 [ms](../ms/AUTO-COMBO.md) · 🇳🇱 [nl](../nl/AUTO-COMBO.md) · 🇵🇱 [pl](../pl/AUTO-COMBO.md) · 🇸🇪 [sv](../sv/AUTO-COMBO.md) · 🇳🇴 [no](../no/AUTO-COMBO.md) · 🇩🇰 [da](../da/AUTO-COMBO.md) · 🇫🇮 [fi](../fi/AUTO-COMBO.md) · 🇵🇹 [pt](../pt/AUTO-COMBO.md) · 🇷🇴 [ro](../ro/AUTO-COMBO.md) · 🇭🇺 [hu](../hu/AUTO-COMBO.md) · 🇧🇬 [bg](../bg/AUTO-COMBO.md) · 🇸🇰 [sk](../sk/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../uk-UA/AUTO-COMBO.md) · 🇮🇱 [he](../he/AUTO-COMBO.md) · 🇵🇭 [phi](../phi/AUTO-COMBO.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute Auto-Combo Engine
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
|
||||
## How It Works
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
|
||||
| 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 |
|
||||
|
||||
## Mode Packs
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
curl -X POST http://localhost:20128/api/combos/auto \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
|
||||
|
||||
# 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).
|
||||
|
||||
## 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 |
|
||||
351
docs/i18n/ar/CLI-TOOLS.md
Normal file
351
docs/i18n/ar/CLI-TOOLS.md
Normal file
@@ -0,0 +1,351 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CLI-TOOLS.md) · 🇧🇷 [pt-BR](../pt-BR/CLI-TOOLS.md) · 🇪🇸 [es](../es/CLI-TOOLS.md) · 🇫🇷 [fr](../fr/CLI-TOOLS.md) · 🇩🇪 [de](../de/CLI-TOOLS.md) · 🇮🇹 [it](../it/CLI-TOOLS.md) · 🇷🇺 [ru](../ru/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../zh-CN/CLI-TOOLS.md) · 🇯🇵 [ja](../ja/CLI-TOOLS.md) · 🇰🇷 [ko](../ko/CLI-TOOLS.md) · 🇸🇦 [ar](../ar/CLI-TOOLS.md)
|
||||
|
||||
# دليل إعداد أدوات CLI — OmniRoute
|
||||
|
||||
يشرح هذا الدليل كيفية تثبيت وتهيئة جميع أدوات CLI المدعومة لاستخدام **OmniRoute** كخلفية موحدة.
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
|
||||
│
|
||||
▼ (all point to OmniRoute)
|
||||
http://YOUR_SERVER:20128/v1
|
||||
│
|
||||
▼ (OmniRoute routes to the right provider)
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## Supported Tools
|
||||
|
||||
| Tool | Command | Type | Install Method |
|
||||
| ---------------- | ------------------- | ----------------- | -------------- |
|
||||
| **Claude Code** | `claude` | CLI | npm |
|
||||
| **OpenAI Codex** | `codex` | CLI | npm |
|
||||
| **Gemini CLI** | `gemini` | CLI | npm |
|
||||
| **OpenCode** | `opencode` | CLI | npm |
|
||||
| **Cline** | `cline` | CLI + VS Code ext | npm |
|
||||
| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code ext | npm |
|
||||
| **Continue** | guide-based | VS Code ext | VS Code |
|
||||
| **Kiro CLI** | `kiro-cli` | CLI | curl installer |
|
||||
| **Cursor** | `cursor` | Desktop app | Download |
|
||||
| **Droid** | web-based | Built-in agent | OmniRoute |
|
||||
| **OpenClaw** | web-based | Built-in agent | OmniRoute |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
npm install -g @openai/codex
|
||||
|
||||
# Gemini CLI (Google)
|
||||
npm install -g @google/gemini-cli
|
||||
|
||||
# OpenCode
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
npm install -g kilecode
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
|
||||
```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
gemini --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`:
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
# Via CLI:
|
||||
claude config set --global api-base-url http://localhost:20128/v1
|
||||
|
||||
# Or create ~/.claude/settings.json:
|
||||
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
{
|
||||
"apiBaseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
|
||||
### Gemini CLI
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
|
||||
{
|
||||
"apiKey": "sk-your-omniroute-key",
|
||||
"baseUrl": "http://localhost:20128/v1"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `gemini "hello"`
|
||||
|
||||
---
|
||||
|
||||
### OpenCode
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"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**.
|
||||
|
||||
---
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
|
||||
---
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
model: auto
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
```bash
|
||||
# Login to your AWS/Kiro account:
|
||||
kiro-cli login
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | 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 |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| 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"` |
|
||||
|
||||
---
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
```bash
|
||||
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
|
||||
OMNIROUTE_URL="http://localhost:20128/v1"
|
||||
OMNIROUTE_KEY="sk-your-omniroute-key"
|
||||
|
||||
npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode
|
||||
|
||||
# Kiro CLI
|
||||
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
|
||||
|
||||
# Write configs
|
||||
mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue
|
||||
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}"
|
||||
cat >> ~/.bashrc << EOF
|
||||
export OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
export OPENAI_API_KEY="$OMNIROUTE_KEY"
|
||||
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
|
||||
EOF
|
||||
|
||||
source ~/.bashrc
|
||||
echo "✅ All CLIs installed and configured for OmniRoute"
|
||||
```
|
||||
@@ -1,22 +1,26 @@
|
||||
# الطريق الشامل - وثائق قاعدة التعليمات البرمجية
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> دليل شامل ومناسب للمبتدئين إلى جهاز التوجيه الوكيل AI **omniroute** متعدد الموفرين.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../es/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../fr/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../de/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../it/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../ru/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../zh-CN/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../ja/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../ko/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../ar/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../in/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../th/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../vi/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../id/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../ms/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../nl/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../pl/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../sv/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../no/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../da/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../fi/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../pt/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../ro/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../hu/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../bg/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../sk/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../uk-UA/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../he/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. ما هو الطريق الشامل؟
|
||||
# omniroute — Codebase Documentation
|
||||
|
||||
omniroute هو **جهاز توجيه وكيل** يقع بين عملاء الذكاء الاصطناعي (Claude CLI، وCodex، وCursor IDE، وما إلى ذلك) وموفري الذكاء الاصطناعي (Anthropic، وGoogle، وOpenAI، وAWS، وGitHub، وما إلى ذلك). إنه يحل مشكلة واحدة كبيرة:
|
||||
🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> **يتحدث عملاء الذكاء الاصطناعي المختلفون "لغات" مختلفة (تنسيقات واجهة برمجة التطبيقات)، ويتوقع مقدمو خدمات الذكاء الاصطناعي المختلفون "لغات" مختلفة أيضًا. ** يترجم المسار الشامل بينهم تلقائيًا.
|
||||
|
||||
فكر في الأمر وكأنه مترجم عالمي في الأمم المتحدة - يمكن لأي مندوب التحدث بأي لغة، ويقوم المترجم بتحويلها لأي مندوب آخر.
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
---
|
||||
|
||||
## 2. نظرة عامة على الهندسة المعمارية
|
||||
## 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
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -61,20 +65,20 @@ graph LR
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### المبدأ الأساسي: الترجمة المحورية
|
||||
### Core Principle: Hub-and-Spoke Translation
|
||||
|
||||
تمر جميع ترجمة التنسيقات عبر **تنسيق OpenAI كمركز**:
|
||||
All format translation passes through **OpenAI format as the hub**:
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
هذا يعني أنك تحتاج فقط إلى مترجمين **N** (واحد لكل تنسيق) بدلاً من **N²** (كل زوج).
|
||||
This means you only need **N translators** (one per format) instead of **N²** (every pair).
|
||||
|
||||
---
|
||||
|
||||
## 3. هيكل المشروع
|
||||
## 3. Project Structure
|
||||
|
||||
```
|
||||
omniroute/
|
||||
@@ -104,22 +108,22 @@ omniroute/
|
||||
|
||||
---
|
||||
|
||||
## 4. تفصيل الوحدة تلو الأخرى
|
||||
## 4. Module-by-Module Breakdown
|
||||
|
||||
### 4.1 التكوين (`open-sse/config/`)
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
**المصدر الوحيد للحقيقة** لجميع إعدادات الموفر.
|
||||
The **single source of truth** for all provider configuration.
|
||||
|
||||
| ملف | الغرض |
|
||||
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | كائن `PROVIDERS` يحتوي على عناوين URL الأساسية وبيانات اعتماد OAuth (الافتراضية) والرؤوس ومطالبات النظام الافتراضية لكل موفر. يحدد أيضًا `HTTP_STATUS`، و`ERROR_TYPES`، و`COOLDOWN_MS`، و`BACKOFF_CONFIG`، و`SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | يقوم بتحميل بيانات الاعتماد الخارجية من `data/provider-credentials.json` ويدمجها في الإعدادات الافتراضية المشفرة في `PROVIDERS`. يحافظ على الأسرار خارج نطاق التحكم بالمصدر مع الحفاظ على التوافق مع الإصدارات السابقة. |
|
||||
| `providerModels.ts` | سجل النموذج المركزي: الأسماء المستعارة لموفر الخرائط → معرفات النموذج. وظائف مثل `getModels()`، `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | تعليمات النظام التي تم إدخالها في طلبات الدستور الغذائي (قيود التحرير، قواعد الاختبار، سياسات الموافقة). |
|
||||
| `defaultThinkingSignature.ts` | توقيعات "التفكير" الافتراضية لنماذج كلود وجيميني. |
|
||||
| `ollamaModels.ts` | تعريف المخطط لنماذج أولاما المحلية (الاسم، الحجم، العائلة، التكميم). |
|
||||
| File | Purpose |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
|
||||
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
|
||||
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
|
||||
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
|
||||
|
||||
#### تدفق تحميل بيانات الاعتماد
|
||||
#### Credential Loading Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -142,9 +146,9 @@ flowchart TD
|
||||
|
||||
---
|
||||
|
||||
### 4.2 المنفذون (`open-sse/executors/`)
|
||||
### 4.2 Executors (`open-sse/executors/`)
|
||||
|
||||
يقوم المنفذون بتغليف **المنطق الخاص بالمزود** باستخدام **نمط الإستراتيجية**. يتجاوز كل منفذ الأساليب الأساسية حسب الحاجة.
|
||||
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
@@ -194,32 +198,32 @@ classDiagram
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| المنفذ | مقدم | التخصصات الرئيسية |
|
||||
| ---------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | قاعدة الملخصات: إنشاء عنوان URL، والرؤوس، ومنطق إعادة المحاولة، وتحديث بيانات الاعتماد |
|
||||
| `default.ts` | كلود، جيميني، أوبن آي آي، جي إل إم، كيمي، ميني ماكس | تحديث رمز OAuth العام للموفرين القياسيين |
|
||||
| `antigravity.ts` | جوجل كلاود كود | إنشاء معرف المشروع/الجلسة، وإرجاع عناوين URL المتعددة، وإعادة محاولة التحليل المخصصة من رسائل الخطأ ("إعادة التعيين بعد 2 ساعة و7 دقائق و23 ثانية") |
|
||||
| `cursor.ts` | بيئة تطوير متكاملة للمؤشر | **الأكثر تعقيدًا**: مصادقة المجموع الاختباري SHA-256، وترميز طلب Protobuf، وEventStream الثنائي → تحليل استجابة SSE |
|
||||
| `codex.ts` | OpenAI Codex | إدخال تعليمات النظام، وإدارة مستويات التفكير، وإزالة المعلمات غير المدعومة |
|
||||
| `gemini-cli.ts` | جوجل الجوزاء CLI | بناء عنوان URL المخصص (`streamGenerateContent`)، تحديث رمز OAuth المميز لـ Google |
|
||||
| `github.ts` | جيثب مساعد الطيار | نظام الرمز المزدوج (GitHub OAuth + Copilot token)، محاكاة رأس VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | التحليل الثنائي لـ AWS EventStream، وإطارات أحداث AMZN، وتقدير الرمز المميز |
|
||||
| `index.ts` | — | المصنع: اسم موفر الخرائط ← فئة المنفذ، مع خيار احتياطي افتراضي |
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
### 4.3 المعالجات (`open-sse/handlers/`)
|
||||
### 4.3 Handlers (`open-sse/handlers/`)
|
||||
|
||||
**طبقة التنسيق** — تتولى تنسيق الترجمة والتنفيذ والتدفق ومعالجة الأخطاء.
|
||||
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
|
||||
|
||||
| ملف | الغرض |
|
||||
| --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | ** المنسق المركزي ** (~ 600 سطر). يتعامل مع دورة حياة الطلب الكاملة: اكتشاف التنسيق ← الترجمة ← إرسال المنفذ ← استجابة التدفق/غير المتدفق ← تحديث الرمز المميز ← معالجة الأخطاء ← تسجيل الاستخدام. |
|
||||
| `responsesHandler.ts` | محول واجهة برمجة تطبيقات استجابات OpenAI: يحول تنسيق الردود ← إكمالات الدردشة ← يرسل إلى `chatCore` ← يحول SSE مرة أخرى إلى تنسيق الردود. |
|
||||
| `embeddings.ts` | معالج إنشاء التضمين: يحل نموذج التضمين → الموفر، ويرسل إلى واجهة برمجة تطبيقات الموفر، ويعيد استجابة التضمين المتوافقة مع OpenAI. يدعم 6+ مقدمي الخدمات. |
|
||||
| `imageGeneration.ts` | معالج إنشاء الصور: يحل نموذج الصورة → الموفر، ويدعم الأوضاع المتوافقة مع OpenAI، وGemini-image (Antigravity)، والوضع الاحتياطي (Nebius). إرجاع صور base64 أو URL. |
|
||||
| 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. |
|
||||
|
||||
#### دورة حياة الطلب (chatCore.ts)
|
||||
#### Request Lifecycle (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -258,28 +262,28 @@ sequenceDiagram
|
||||
|
||||
---
|
||||
|
||||
### 4.4 الخدمات (`open-sse/services/`)
|
||||
### 4.4 Services (`open-sse/services/`)
|
||||
|
||||
منطق الأعمال الذي يدعم المعالجات والمنفذين.
|
||||
Business logic that supports the handlers and executors.
|
||||
|
||||
| ملف | الغرض |
|
||||
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **كشف التنسيق** (`detectFormat`): تحليلات بنية الجسم لتحديد تنسيقات Claude/OpenAI/Gemini/Antigravity/Responses (تتضمن `max_tokens` الاستدلال لكلود). أيضًا: بناء عنوان URL، وبناء الرأس، وتطبيع تكوين التفكير. يدعم موفري الخدمات الديناميكيين `openai-compatible-*` و`anthropic-compatible-*`. |
|
||||
| `model.ts` | تحليل سلسلة النموذج (`claude/model-name` → `{provider: "claude", model: "model-name"}`)، ودقة الاسم المستعار مع اكتشاف التصادم، وتعقيم الإدخال (يرفض أحرف اجتياز المسار/التحكم)، ودقة معلومات النموذج مع دعم getter للاسم المستعار غير المتزامن. |
|
||||
| `accountFallback.ts` | التعامل مع الحد الأقصى للمعدل: التراجع الأسي (1s → 2s → 4s → 2min كحد أقصى)، وإدارة فترة تهدئة الحساب، وتصنيف الأخطاء (أي الأخطاء تؤدي إلى التراجع مقابل عدم حدوثه). |
|
||||
| `tokenRefresh.ts` | تحديث رمز OAuth المميز **لكل مزود**: Google (Gemini، Antigravity)، Claude، Codex، Qwen، iFlow، GitHub (OAuth + Copilot Dual-Token)، Kiro (AWS SSO OIDC + Social Auth). يتضمن ذاكرة تخزين مؤقت لإلغاء البيانات المكررة أثناء الرحلة وإعادة المحاولة مع التراجع المتسارع. |
|
||||
| `combo.ts` | **نماذج مجمعة**: سلاسل من النماذج الاحتياطية. إذا فشل النموذج A مع وجود خطأ مؤهل للرجوع إليه، فجرّب النموذج B، ثم C، وما إلى ذلك. يقوم بإرجاع رموز الحالة الأولية الفعلية. |
|
||||
| `usage.ts` | جلب بيانات الحصص/الاستخدام من واجهات برمجة تطبيقات الموفر (حصص GitHub Copilot، وحصص نماذج Antigravity، وحدود معدل Codex، وأعطال استخدام Kiro، وإعدادات Claude). |
|
||||
| `accountSelector.ts` | اختيار الحساب الذكي باستخدام خوارزمية التسجيل: يأخذ في الاعتبار الأولوية والحالة الصحية والموضع الدائري وحالة التهدئة لاختيار الحساب الأمثل لكل طلب. |
|
||||
| `contextManager.ts` | إدارة دورة حياة سياق الطلب: إنشاء وتتبع كائنات السياق لكل طلب باستخدام بيانات التعريف (معرف الطلب، والطوابع الزمنية، ومعلومات الموفر) لتصحيح الأخطاء والتسجيل. |
|
||||
| `ipFilter.ts` | التحكم في الوصول المستند إلى IP: يدعم وضعي القائمة المسموح بها والقائمة المحظورة. التحقق من صحة عنوان IP للعميل مقابل القواعد التي تم تكوينها قبل معالجة طلبات واجهة برمجة التطبيقات. |
|
||||
| `sessionManager.ts` | تتبع الجلسة باستخدام بصمة العميل: يتتبع الجلسات النشطة باستخدام معرفات العميل المجزأة، ويراقب عدد الطلبات، ويوفر مقاييس الجلسة. |
|
||||
| `signatureCache.ts` | طلب ذاكرة التخزين المؤقت لإلغاء البيانات المكررة المستندة إلى التوقيع: يمنع الطلبات المكررة عن طريق تخزين توقيعات الطلب الأخيرة مؤقتًا وإرجاع الاستجابات المخزنة مؤقتًا للطلبات المتطابقة خلال نافذة زمنية. |
|
||||
| `systemPrompt.ts` | الحقن الفوري للنظام العالمي: يُلحق أو يُلحق موجه نظام قابل للتكوين لجميع الطلبات، مع معالجة التوافق لكل مزود. |
|
||||
| `thinkingBudget.ts` | إدارة ميزانية الرموز المميزة: تدعم أوضاع المرور، والتلقائي (تكوين التفكير الشريطي)، والمخصص (الميزانية الثابتة)، والتكيفية (مدرجة التعقيد) للتحكم في رموز التفكير/الاستدلال. |
|
||||
| `wildcardRouter.ts` | توجيه نمط نموذج حرف البدل: يحل أنماط حرف البدل (على سبيل المثال، `*/claude-*`) لأزواج الموفر/النموذج الملموسة بناءً على التوفر والأولوية. |
|
||||
| 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, iFlow, 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
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -300,7 +304,7 @@ sequenceDiagram
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### آلة الحالة الاحتياطية للحساب
|
||||
#### Account Fallback State Machine
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
@@ -325,7 +329,7 @@ stateDiagram-v2
|
||||
}
|
||||
```
|
||||
|
||||
#### سلسلة نماذج كومبو
|
||||
#### Combo Model Chain
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -344,11 +348,11 @@ flowchart LR
|
||||
|
||||
---
|
||||
|
||||
### مترجم 4.5 (`open-sse/translator/`)
|
||||
### 4.5 Translator (`open-sse/translator/`)
|
||||
|
||||
**محرك ترجمة التنسيق** باستخدام نظام إضافي للتسجيل الذاتي.
|
||||
The **format translation engine** using a self-registering plugin system.
|
||||
|
||||
####الهندسة المعمارية
|
||||
#### Architecture
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
@@ -374,15 +378,15 @@ graph TD
|
||||
end
|
||||
```
|
||||
|
||||
| الدليل | ملفات | الوصف |
|
||||
| ------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 مترجمين | تحويل أجسام الطلب بين الصيغ. يتم تسجيل كل ملف ذاتيًا عبر `register(from, to, fn)` عند الاستيراد. |
|
||||
| `response/` | 7 مترجمين | تحويل قطع الاستجابة المتدفقة بين الصيغ. يتعامل مع أنواع أحداث SSE وكتل التفكير واستدعاءات الأدوات. |
|
||||
| `helpers/` | 6 مساعدين | الأدوات المساعدة المشتركة: `claudeHelper` (استخراج موجه النظام، تكوين التفكير)، `geminiHelper` (تعيين الأجزاء/المحتويات)، `openaiHelper` (تصفية التنسيق)، `toolCallHelper` (إنشاء المعرف، حقن الاستجابة المفقودة)، `maxTokensHelper`، `responsesApiHelper`. |
|
||||
| `index.ts` | — | محرك الترجمة: `translateRequest()`، `translateResponse()`، إدارة الحالة، التسجيل. |
|
||||
| `formats.ts` | — | ثوابت التنسيق: `OPENAI`، `CLAUDE`، `GEMINI`، `ANTIGRAVITY`، `KIRO`، `CURSOR`، `OPENAI_RESPONSES`. |
|
||||
| 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
|
||||
// Each translator file calls register() on import:
|
||||
@@ -395,19 +399,19 @@ import "./request/claude-to-openai.js"; // ← self-registers
|
||||
|
||||
---
|
||||
|
||||
### 4.6 الأدوات المساعدة (`open-sse/utils/`)
|
||||
### 4.6 Utils (`open-sse/utils/`)
|
||||
|
||||
| ملف | الغرض |
|
||||
| ------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `error.ts` | إنشاء استجابة للأخطاء (تنسيق متوافق مع OpenAI)، وتحليل الأخطاء الأولية، واستخراج وقت إعادة محاولة Antigravity من رسائل الخطأ، وتدفق أخطاء SSE. |
|
||||
| `stream.ts` | **SSE Transform Stream** — خط أنابيب البث الأساسي. وضعان: `TRANSLATE` (ترجمة التنسيق الكامل) و`PASSTHROUGH` (تطبيع + استخراج الاستخدام). يتعامل مع التخزين المؤقت للقطعة وتقدير الاستخدام وتتبع طول المحتوى. تتجنب مثيلات وحدة التشفير/وحدة فك التشفير لكل تيار الحالة المشتركة. |
|
||||
| `streamHelpers.ts` | أدوات SSE ذات المستوى المنخفض: `parseSSELine` (تتحمل المسافات البيضاء)، `hasValuableContent` (تصفية الأجزاء الفارغة لـ OpenAI/Claude/Gemini)، `fixInvalidId`، `formatSSE` (تسلسل SSE مدرك للتنسيق مع تنظيف `perf_metrics`). |
|
||||
| `usageTracking.ts` | استخراج استخدام الرمز المميز من أي تنسيق (Claude/OpenAI/Gemini/Responses)، والتقدير باستخدام نسب الأحرف لكل رمز مميز للأداة/الرسالة، وإضافة المخزن المؤقت (هامش أمان 2000 رمز مميز)، وتصفية الحقول الخاصة بالتنسيق، وتسجيل وحدة التحكم بألوان ANSI. |
|
||||
| `requestLogger.ts` | تسجيل الطلب المستند إلى الملف (الاشتراك عبر `ENABLE_REQUEST_LOGS=true`). ينشئ مجلدات الجلسة بملفات مرقمة: `1_req_client.json` → `7_res_client.txt`. كل عمليات الإدخال/الإخراج غير متزامنة (أطلق النار وانسى). أقنعة الرؤوس الحساسة. |
|
||||
| `bypassHandler.ts` | يعترض أنماطًا محددة من Claude CLI (استخراج العنوان، والتحمية، والعد) ويعيد استجابات مزيفة دون الاتصال بأي مزود. يدعم كلا من الدفق وغير الدفق. يقتصر عمدا على نطاق كلود CLI. |
|
||||
| `networkProxy.ts` | يحل عنوان URL للوكيل الصادر لموفر معين مع الأسبقية: التكوين الخاص بالموفر → التكوين العام → متغيرات البيئة (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). يدعم استثناءات `NO_PROXY`. تكوين ذاكرة التخزين المؤقت لمدة 30 ثانية. |
|
||||
| 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
|
||||
#### SSE Streaming Pipeline
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -429,7 +433,7 @@ flowchart TD
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### بنية جلسة مسجل الطلب
|
||||
#### Request Logger Session Structure
|
||||
|
||||
```
|
||||
logs/
|
||||
@@ -447,109 +451,109 @@ logs/
|
||||
|
||||
---
|
||||
|
||||
### 4.7 طبقة التطبيق (`src/`)
|
||||
### 4.7 Application Layer (`src/`)
|
||||
|
||||
| الدليل | الغرض |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `src/app/` | واجهة مستخدم الويب، مسارات واجهة برمجة التطبيقات (API)، البرامج الوسيطة السريعة، معالجات رد اتصال OAuth |
|
||||
| `src/lib/` | الوصول إلى قاعدة البيانات (`localDb.ts`، `usageDb.ts`)، المصادقة، مشتركة |
|
||||
| `src/mitm/` | أدوات مساعدة للوكيل الوسيط لاعتراض حركة مرور الموفر |
|
||||
| `src/models/` | تعريفات نماذج قواعد البيانات |
|
||||
| `src/shared/` | أغلفة حول وظائف open-sse (المزود، الدفق، الخطأ، إلخ) |
|
||||
| `src/sse/` | معالجات نقطة نهاية SSE التي تربط مكتبة open-sse بمسارات Express |
|
||||
| `src/store/` | إدارة حالة التطبيق |
|
||||
| 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 |
|
||||
|
||||
#### مسارات API البارزة
|
||||
#### Notable API Routes
|
||||
|
||||
| الطريق | طرق | الغرض |
|
||||
| --------------------------------------------- | ------------------ | ------------------------------------------------------------------------------ |
|
||||
| `/api/provider-models` | الحصول على/نشر/حذف | CRUD للنماذج المخصصة لكل مزود |
|
||||
| `/api/models/catalog` | احصل على | كتالوج مجمع لجميع النماذج (الدردشة، التضمين، الصورة، المخصصة) مجمعة حسب الموفر |
|
||||
| `/api/settings/proxy` | الحصول على/وضع/حذف | تكوين الوكيل الصادر الهرمي (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | مشاركة | التحقق من صحة اتصال الوكيل وإرجاع IP/زمن الوصول العام |
|
||||
| `/v1/providers/[provider]/chat/completions` | مشاركة | عمليات إكمال الدردشة المخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/v1/providers/[provider]/embeddings` | مشاركة | عمليات التضمين المخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/v1/providers/[provider]/images/generations` | مشاركة | إنشاء صور مخصصة لكل مزود مع التحقق من صحة النموذج |
|
||||
| `/api/settings/ip-filter` | الحصول على/وضع | قائمة IP المسموح بها/إدارة القائمة المحظورة |
|
||||
| `/api/settings/thinking-budget` | الحصول على/وضع | تكوين ميزانية الرمز المميز (العبور/التلقائي/المخصص/التكيفي) |
|
||||
| `/api/settings/system-prompt` | الحصول على/وضع | الحقن الفوري للنظام العالمي لجميع الطلبات |
|
||||
| `/api/sessions` | احصل على | تتبع الجلسة النشطة ومقاييسها |
|
||||
| `/api/rate-limits` | احصل على | حالة حد المعدل لكل حساب |
|
||||
| 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. أنماط التصميم الرئيسية
|
||||
## 5. Key Design Patterns
|
||||
|
||||
### 5.1 الترجمة المحورية والمتحدثة
|
||||
### 5.1 Hub-and-Spoke Translation
|
||||
|
||||
تتم ترجمة جميع التنسيقات من خلال **تنسيق OpenAI كمحور**. لا تتطلب إضافة موفر جديد سوى كتابة **زوج واحد** من المترجمين (من/إلى OpenAI)، وليس عدد N من المترجمين.
|
||||
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.
|
||||
|
||||
### 5.2 نمط استراتيجية المنفذ
|
||||
### 5.2 Executor Strategy Pattern
|
||||
|
||||
كل مزود لديه فئة منفذة مخصصة ترث من `BaseExecutor`. يقوم المصنع في `executors/index.ts` باختيار المصنع المناسب في وقت التشغيل.
|
||||
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
|
||||
|
||||
### 5.3 نظام البرنامج المساعد للتسجيل الذاتي
|
||||
### 5.3 Self-Registering Plugin System
|
||||
|
||||
تسجل وحدات المترجم نفسها عند الاستيراد عبر `register()`. إن إضافة مترجم جديد يعني مجرد إنشاء ملف واستيراده.
|
||||
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
|
||||
|
||||
### 5.4 التراجع في الحساب مع التراجع الأسي
|
||||
### 5.4 Account Fallback with Exponential Backoff
|
||||
|
||||
عندما يقوم مقدم الخدمة بإرجاع 429/401/500، يمكن للنظام التبديل إلى الحساب التالي، مع تطبيق فترات التباطؤ الأسية (1ث → 2ث → 4ث → 2 دقيقة كحد أقصى).
|
||||
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 سلاسل نماذج كومبو
|
||||
### 5.5 Combo Model Chains
|
||||
|
||||
يقوم "التحرير والسرد" بتجميع سلاسل `provider/model` متعددة. إذا فشل الأول، يتم الرجوع إلى التالي تلقائيًا.
|
||||
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
|
||||
|
||||
### 5.6 ترجمة متدفقة رائعة
|
||||
### 5.6 Stateful Streaming Translation
|
||||
|
||||
تحافظ ترجمة الاستجابة على الحالة عبر أجزاء SSE (تتبع كتلة التفكير، وتراكم استدعاءات الأداة، وفهرسة كتلة المحتوى) عبر آلية `initState()`.
|
||||
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
|
||||
|
||||
### 5.7 المخزن المؤقت لسلامة الاستخدام
|
||||
### 5.7 Usage Safety Buffer
|
||||
|
||||
تتم إضافة مخزن مؤقت مكون من 2000 رمز مميز إلى الاستخدام المبلغ عنه لمنع العملاء من الوصول إلى حدود نافذة السياق بسبب الحمل الزائد من مطالبات النظام وترجمة التنسيق.
|
||||
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. التنسيقات المدعومة
|
||||
## 6. Supported Formats
|
||||
|
||||
| تنسيق | الاتجاه | المعرف |
|
||||
| ----------------------------------- | -------------- | ------------------ |
|
||||
| استكمالات الدردشة OpenAI | المصدر + الهدف | `openai` |
|
||||
| واجهة برمجة تطبيقات استجابات OpenAI | المصدر + الهدف | `openai-responses` |
|
||||
| أنثروبي كلود | المصدر + الهدف | `claude` |
|
||||
| جوجل الجوزاء | المصدر + الهدف | `gemini` |
|
||||
| جوجل الجوزاء CLI | الهدف فقط | `gemini-cli` |
|
||||
| مكافحة الجاذبية | المصدر + الهدف | `antigravity` |
|
||||
| أوس كيرو | الهدف فقط | `kiro` |
|
||||
| المؤشر | الهدف فقط | `cursor` |
|
||||
| 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` |
|
||||
|
||||
---
|
||||
|
||||
## 7. مقدمو الخدمة المدعومين
|
||||
## 7. Supported Providers
|
||||
|
||||
| مقدم | طريقة المصادقة | المنفذ | الملاحظات الرئيسية |
|
||||
| ------------------------- | ------------------------ | --------------- | --------------------------------------------------------- |
|
||||
| أنثروبي كلود | مفتاح API أو OAuth | الافتراضي | يستخدم رأس `x-api-key` |
|
||||
| جوجل الجوزاء | مفتاح API أو OAuth | الافتراضي | يستخدم رأس `x-goog-api-key` |
|
||||
| جوجل الجوزاء CLI | أووث | الجوزاء كلي | يستخدم `streamGenerateContent` نقطة النهاية |
|
||||
| مكافحة الجاذبية | أووث | مكافحة الجاذبية | احتياطي عناوين URL المتعددة، إعادة محاولة التحليل المخصصة |
|
||||
| أوبن آي | مفتاح API | الافتراضي | مصادقة حامل المعيار |
|
||||
| الدستور الغذائي | أووث | الدستور الغذائي | يدخل تعليمات النظام ويدير التفكير |
|
||||
| جيثب مساعد الطيار | OAuth + رمز مساعد الطيار | جيثب | رمز مزدوج، محاكاة رأس VSCode |
|
||||
| كيرو (AWS) | AWS SSO OIDC أو Social | كيرو | تحليل دفق الأحداث الثنائية |
|
||||
| بيئة تطوير متكاملة للمؤشر | مصادقة المجموع الاختباري | المؤشر | ترميز Protobuf، المجموع الاختباري SHA-256 |
|
||||
| كوين | أووث | الافتراضي | المصادقة القياسية |
|
||||
| اي فلو | OAuth (أساسي + حامل) | الافتراضي | رأس المصادقة المزدوجة |
|
||||
| اوبن راوتر | مفتاح API | الافتراضي | مصادقة حامل المعيار |
|
||||
| جي إل إم، كيمي، ميني ماكس | مفتاح API | الافتراضي | متوافق مع كلود، استخدم `x-api-key` |
|
||||
| `openai-compatible-*` | مفتاح API | الافتراضي | ديناميكي: أي نقطة نهاية متوافقة مع OpenAI |
|
||||
| `anthropic-compatible-*` | مفتاح API | الافتراضي | ديناميكي: أي نقطة نهاية متوافقة مع كلود |
|
||||
| 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 |
|
||||
| iFlow | 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. ملخص تدفق البيانات
|
||||
## 8. Data Flow Summary
|
||||
|
||||
### طلب البث
|
||||
### Streaming Request
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -566,7 +570,7 @@ flowchart LR
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### طلب عدم البث
|
||||
### Non-Streaming Request
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -577,7 +581,7 @@ flowchart LR
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### تجاوز التدفق (كلود CLI)
|
||||
### Bypass Flow (Claude CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
@@ -1,77 +1,147 @@
|
||||
# OmniRoute — معرض ميزات لوحة المعلومات
|
||||
# OmniRoute — Dashboard Features Gallery (العربية)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) · 🇪🇸 [es](../es/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇩🇪 [de](../de/README.md) · 🇮🇹 [it](../it/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇸🇦 [ar](../ar/README.md) · 🇮🇳 [in](../in/README.md) · 🇹🇭 [th](../th/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇮🇩 [id](../id/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇳🇴 [no](../no/README.md) · 🇩🇰 [da](../da/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇮🇱 [he](../he/README.md) · 🇵🇭 [phi](../phi/README.md)
|
||||
|
||||
دليل مرئي لكل قسم من لوحة معلومات OmniRoute.
|
||||
> 🇺🇸 [English](../../../docs/FEATURES.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔌 مقدمو الخدمة
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
إدارة اتصالات مزودي الذكاء الاصطناعي: موفري OAuth (Claude Code وCodex وGemini CLI) وموفري مفاتيح API (Groq وDeepSeek وOpenRouter) ومقدمي الخدمات المجانية (iFlow وQwen وKiro).
|
||||
---
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (iFlow, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

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

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

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

|
||||
|
||||
---
|
||||
|
||||
## 🔧 ملعب المترجم
|
||||
## 🔧 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+)_
|
||||
|
||||
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
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning
|
||||
- **Advanced** — Configuration overrides
|
||||
|
||||

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

|
||||
|
||||
---
|
||||
|
||||
## 📝 سجلات الطلب
|
||||
## 🤖 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:
|
||||
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ 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
|
||||
## 🌐 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. Cloud proxy support for remote access.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔑 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.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Audit Log
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ 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.
|
||||
|
||||
87
docs/i18n/ar/MCP-SERVER.md
Normal file
87
docs/i18n/ar/MCP-SERVER.md
Normal file
@@ -0,0 +1,87 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/MCP-SERVER.md) · 🇪🇸 [es](../es/MCP-SERVER.md) · 🇫🇷 [fr](../fr/MCP-SERVER.md) · 🇩🇪 [de](../de/MCP-SERVER.md) · 🇮🇹 [it](../it/MCP-SERVER.md) · 🇷🇺 [ru](../ru/MCP-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/MCP-SERVER.md) · 🇯🇵 [ja](../ja/MCP-SERVER.md) · 🇰🇷 [ko](../ko/MCP-SERVER.md) · 🇸🇦 [ar](../ar/MCP-SERVER.md) · 🇮🇳 [in](../in/MCP-SERVER.md) · 🇹🇭 [th](../th/MCP-SERVER.md) · 🇻🇳 [vi](../vi/MCP-SERVER.md) · 🇮🇩 [id](../id/MCP-SERVER.md) · 🇲🇾 [ms](../ms/MCP-SERVER.md) · 🇳🇱 [nl](../nl/MCP-SERVER.md) · 🇵🇱 [pl](../pl/MCP-SERVER.md) · 🇸🇪 [sv](../sv/MCP-SERVER.md) · 🇳🇴 [no](../no/MCP-SERVER.md) · 🇩🇰 [da](../da/MCP-SERVER.md) · 🇫🇮 [fi](../fi/MCP-SERVER.md) · 🇵🇹 [pt](../pt/MCP-SERVER.md) · 🇷🇴 [ro](../ro/MCP-SERVER.md) · 🇭🇺 [hu](../hu/MCP-SERVER.md) · 🇧🇬 [bg](../bg/MCP-SERVER.md) · 🇸🇰 [sk](../sk/MCP-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/MCP-SERVER.md) · 🇮🇱 [he](../he/MCP-SERVER.md) · 🇵🇭 [phi](../phi/MCP-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute MCP Server Documentation
|
||||
|
||||
> Model Context Protocol server with 16 intelligent tools
|
||||
|
||||
## Installation
|
||||
|
||||
OmniRoute MCP is built-in. Start it with:
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Or via the open-sse transport:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
```
|
||||
|
||||
## IDE Configuration
|
||||
|
||||
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
## 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 |
|
||||
| `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 |
|
||||
|
||||
## Authentication
|
||||
|
||||
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 |
|
||||
|
||||
## 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 |
|
||||
@@ -8,6 +8,16 @@ _وكيل API العالمي الخاص بك - نقطة نهاية واحدة،
|
||||
|
||||
---
|
||||
|
||||
### 🆕 الجديد في v2.7.0
|
||||
|
||||
- **RouterStrategy قابل للتوصيل** — استراتيجيات القواعد والتكلفة والكمون
|
||||
- **كشف النية متعدد اللغات** — تسجيل التوجيه بأكثر من 30 لغة
|
||||
- **إلغاء تكرار الطلبات** — تجنب مكالمات API المكررة عبر تجزئة المحتوى
|
||||
- **مزودون جدد:** Grok-4 Fast (xAI) وGLM-5 / Z.AI وMiniMax M2.5 وKimi K2.5
|
||||
- **أسعار محدثة:** Grok-4 Fast $0.20/$0.50/M، GLM-5 $0.50/M، MiniMax M2.5 $0.30/M
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
@@ -20,7 +30,7 @@ _وكيل API العالمي الخاص بك - نقطة نهاية واحدة،
|
||||
|
||||
</div>
|
||||
|
||||
🌐 **متوفر باللغة:** 🇺🇸 [الإنجليزية](README.md) | 🇧🇷 [البرتغالية (البرازيل)](README.pt-BR.md) | 🇪🇸 [الإسبانية](README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [الإيطالية](README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [الألمانية](README.de.md) | 🇮🇳 [هندي](README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [أوكرانيا](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [تيانج فيت](README.vi.md) | 🇧🇬 [بلغارسكي](README.bg.md) | 🇩🇰 [الدانسك](README.da.md) | 🇫🇮 [سومي](README.fi.md) | 🇮🇱 [العربية](README.he.md) | 🇭🇺 [المجرية](README.hu.md) | 🇮🇩 [البهاسا الإندونيسية](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [البهاسا ملايو](README.ms.md) | 🇳🇱 [هولندا](README.nl.md) | 🇳🇴 [نورسك](README.no.md) | 🇵🇹 [البرتغالية (البرتغال)](README.pt.md) | 🇷🇴 [روماني](README.ro.md) | 🇵🇱 [بولسكي](README.pl.md) | 🇸🇰 [سلوفينسينا](README.sk.md) | 🇸🇪 [سفينسكا](README.sv.md) | 🇵🇭 [فلبينية](README.phi.md)
|
||||
🌐 **متوفر باللغة:** 🇺🇸 [الإنجليزية](../../README.md) | 🇧🇷 [البرتغالية (البرازيل)](../pt-BR/README.md) | 🇪🇸 [الإسبانية](../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [الإيطالية](../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [الألمانية](../de/README.md) | 🇮🇳 [هندي](../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [أوكرانيا](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [تيانج فيت](../vi/README.md) | 🇧🇬 [بلغارسكي](../bg/README.md) | 🇩🇰 [الدانسك](../da/README.md) | 🇫🇮 [سومي](../fi/README.md) | 🇮🇱 [العربية](../he/README.md) | 🇭🇺 [المجرية](../hu/README.md) | 🇮🇩 [البهاسا الإندونيسية](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [البهاسا ملايو](../ms/README.md) | 🇳🇱 [هولندا](../nl/README.md) | 🇳🇴 [نورسك](../no/README.md) | 🇵🇹 [البرتغالية (البرتغال)](../pt/README.md) | 🇷🇴 [روماني](../ro/README.md) | 🇵🇱 [بولسكي](../pl/README.md) | 🇸🇰 [سلوفينسينا](../sk/README.md) | 🇸🇪 [سفينسكا](../sv/README.md) | 🇵🇭 [فلبينية](../phi/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -53,6 +63,18 @@ _وكيل API العالمي الخاص بك - نقطة نهاية واحدة،
|
||||
|
||||
---
|
||||
|
||||
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
|
||||
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
|
||||
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
|
||||
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
|
||||
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
|
||||
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
|
||||
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
|
||||
|
||||
### 🤖 موفر الذكاء الاصطناعي المجاني لوكلاء البرمجة المفضلين لديك
|
||||
|
||||
_قم بتوصيل أي أداة IDE أو CLI مدعومة بالذكاء الاصطناعي من خلال OmniRoute - بوابة واجهة برمجة التطبيقات المجانية للترميز غير المحدود._
|
||||
@@ -253,6 +275,7 @@ Result: Never stop coding, minimal cost
|
||||
**كيف يحل OmniRoute المشكلة:**
|
||||
|
||||
- **موفرو الطبقة المجانية المضمنون** — دعم أصلي لمقدمي الخدمات المجانيين بنسبة 100%: iFlow (8 نماذج غير محدودة)، Qwen (3 نماذج غير محدودة)، Kiro (Claude مجانًا)، Gemini CLI (180 ألف/شهر مجانًا)
|
||||
- **Ollama Cloud** — Cloud-hosted Ollama models at `api.ollama.com` with free "Light usage" tier; use `ollamacloud/<model>` prefix
|
||||
- **المجموعات المجانية فقط** — السلسلة `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = 0 USD/الشهر بدون أي توقف عن العمل
|
||||
- **أرصدة NVIDIA NIM المجانية** — 1000 رصيد مجاني مدمج
|
||||
- **استراتيجية التكلفة المحسنة** — استراتيجية التوجيه التي تختار تلقائيًا أرخص مزود متاح
|
||||
@@ -909,8 +932,8 @@ npm run electron:build:linux # Linux (.AppImage)
|
||||
| ميزة | ماذا يفعل || -------------------------- | ------------------------------------------------------------- |
|
||||
| 🖼️ **إنشاء الصور** | `/v1/images/generations` مع الواجهات الخلفية السحابية والمحلية |
|
||||
| 📐 **المضامين** | `/v1/embeddings` للبحث وخطوط أنابيب RAG |
|
||||
| 🎤 **نسخ صوتي** | `/v1/audio/transcriptions` (مقدمو خدمات الهمس والإضافيون) |
|
||||
| 🔊 **تحويل النص إلى كلام** | `/v1/audio/speech` (محركات/موفرو متعددون) |
|
||||
| 🎤 **نسخ صوتي** | `/v1/audio/transcriptions` — 7 providers (Deepgram Nova 3, AssemblyAI, Groq Whisper, HuggingFace, ElevenLabs, OpenAI, Azure), auto-language detection, MP4/MP3/WAV support |
|
||||
| 🔊 **تحويل النص إلى كلام** | `/v1/audio/speech` — 10 providers (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) |
|
||||
| 🎬 **توليد الفيديو** | `/v1/videos/generations` (سير عمل ComfyUI + SD WebUI) |
|
||||
| 🎵 **جيل الموسيقى** | `/v1/music/generations` (سير عمل ComfyUI) |
|
||||
| 🛡️ **اعتدالات** | فحوصات السلامة `/v1/moderations` |
|
||||
@@ -1638,15 +1661,9 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
|
||||
|
||||
## 📊 تاريخ النجوم
|
||||
|
||||
<a href="https://star-history.com/#diegosouzapw/OmniRoute&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
## Stargazers over time
|
||||
|
||||
---
|
||||
## [](https://starchart.cc/diegosouzapw/OmniRoute)
|
||||
|
||||
## 🙏 شكر وتقدير
|
||||
|
||||
37
docs/i18n/ar/RELEASE_CHECKLIST.md
Normal file
37
docs/i18n/ar/RELEASE_CHECKLIST.md
Normal file
@@ -0,0 +1,37 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../es/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../fr/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../de/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../it/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../ru/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../zh-CN/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../ja/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../ko/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../ar/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../in/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../th/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../vi/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../id/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../ms/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../nl/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../pl/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../sv/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../no/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../da/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../fi/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../pt/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../ro/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../hu/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../bg/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../sk/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../uk-UA/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../he/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../phi/RELEASE_CHECKLIST.md)
|
||||
|
||||
---
|
||||
|
||||
# Release Checklist
|
||||
|
||||
Use this checklist before tagging or publishing a new OmniRoute release.
|
||||
|
||||
## Version and Changelog
|
||||
|
||||
1. Bump `package.json` version (`x.y.z`) in the release branch.
|
||||
2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
|
||||
- `## [x.y.z] — YYYY-MM-DD`
|
||||
3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
|
||||
4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
|
||||
|
||||
## API Docs
|
||||
|
||||
1. Update `docs/openapi.yaml`:
|
||||
- `info.version` must equal `package.json` version.
|
||||
2. Validate endpoint examples if API contracts changed.
|
||||
|
||||
## 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).
|
||||
@@ -1,87 +1,91 @@
|
||||
# استكشاف الأخطاء وإصلاحها
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
المشاكل والحلول الشائعة لـ OmniRoute.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/TROUBLESHOOTING.md) · 🇪🇸 [es](../es/TROUBLESHOOTING.md) · 🇫🇷 [fr](../fr/TROUBLESHOOTING.md) · 🇩🇪 [de](../de/TROUBLESHOOTING.md) · 🇮🇹 [it](../it/TROUBLESHOOTING.md) · 🇷🇺 [ru](../ru/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../zh-CN/TROUBLESHOOTING.md) · 🇯🇵 [ja](../ja/TROUBLESHOOTING.md) · 🇰🇷 [ko](../ko/TROUBLESHOOTING.md) · 🇸🇦 [ar](../ar/TROUBLESHOOTING.md) · 🇮🇳 [in](../in/TROUBLESHOOTING.md) · 🇹🇭 [th](../th/TROUBLESHOOTING.md) · 🇻🇳 [vi](../vi/TROUBLESHOOTING.md) · 🇮🇩 [id](../id/TROUBLESHOOTING.md) · 🇲🇾 [ms](../ms/TROUBLESHOOTING.md) · 🇳🇱 [nl](../nl/TROUBLESHOOTING.md) · 🇵🇱 [pl](../pl/TROUBLESHOOTING.md) · 🇸🇪 [sv](../sv/TROUBLESHOOTING.md) · 🇳🇴 [no](../no/TROUBLESHOOTING.md) · 🇩🇰 [da](../da/TROUBLESHOOTING.md) · 🇫🇮 [fi](../fi/TROUBLESHOOTING.md) · 🇵🇹 [pt](../pt/TROUBLESHOOTING.md) · 🇷🇴 [ro](../ro/TROUBLESHOOTING.md) · 🇭🇺 [hu](../hu/TROUBLESHOOTING.md) · 🇧🇬 [bg](../bg/TROUBLESHOOTING.md) · 🇸🇰 [sk](../sk/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../uk-UA/TROUBLESHOOTING.md) · 🇮🇱 [he](../he/TROUBLESHOOTING.md) · 🇵🇭 [phi](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
---
|
||||
|
||||
## إصلاحات سريعة
|
||||
# Troubleshooting
|
||||
|
||||
| مشكلة | الحل |
|
||||
| --------------------------------- | ----------------------------------------------------------------- |
|
||||
| تسجيل الدخول الأول لا يعمل | تحقق من `INITIAL_PASSWORD` في `.env` (الافتراضي: `123456`) |
|
||||
| تفتح لوحة المعلومات على منفذ خاطئ | اضبط `PORT=20128` و`NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| لا توجد سجلات للطلب ضمن `logs/` | تعيين `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: تم رفض الإذن | اضبط `DATA_DIR=/path/to/writable/dir` لتجاوز `~/.omniroute` |
|
||||
| استراتيجية التوجيه لا تنقذ | التحديث إلى الإصدار 1.4.11+ (إصلاح مخطط Zod لاستمرارية الإعدادات) |
|
||||
🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md)
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## مشكلات المزود
|
||||
## Quick Fixes
|
||||
|
||||
### "نموذج اللغة لم يقدم رسائل"
|
||||
|
||||
**السبب:** استنفدت حصة الموفر.
|
||||
|
||||
**الإصلاح:**
|
||||
|
||||
1. تحقق من تعقب الحصص في لوحة القيادة
|
||||
2. استخدم مجموعة من المستويات الاحتياطية
|
||||
3. قم بالتبديل إلى الطبقة الأرخص/المجانية
|
||||
|
||||
### تحديد المعدل
|
||||
|
||||
**السبب:** استنفدت حصة الاشتراك.
|
||||
|
||||
**الإصلاح:**
|
||||
|
||||
- إضافة احتياطي: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- استخدم GLM/MiniMax كنسخة احتياطية رخيصة الثمن
|
||||
|
||||
### انتهت صلاحية رمز OAuth
|
||||
|
||||
يقوم OmniRoute بتحديث الرموز المميزة تلقائيًا. إذا استمرت المشكلات:
|
||||
|
||||
1. لوحة المعلومات → الموفر → إعادة الاتصال
|
||||
2. قم بحذف وإعادة إضافة اتصال الموفر
|
||||
| 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
|
||||
|
||||
### أخطاء المزامنة السحابية
|
||||
### "Language model did not provide messages"
|
||||
|
||||
1. تحقق من نقاط `BASE_URL` لمثيلك قيد التشغيل (على سبيل المثال، `http://localhost:20128`)
|
||||
2. تحقق من نقاط `CLOUD_URL` إلى نقطة نهاية السحابة الخاصة بك (على سبيل المثال، `https://omniroute.dev`)
|
||||
3. حافظ على محاذاة قيم `NEXT_PUBLIC_*` مع القيم من جانب الخادم
|
||||
**Cause:** Provider quota exhausted.
|
||||
|
||||
### السحابة `stream=false` تُرجع 500
|
||||
**Fix:**
|
||||
|
||||
**العَرَض:** `Unexpected token 'd'...` على نقطة نهاية السحابة للمكالمات غير المتدفقة.
|
||||
1. Check dashboard quota tracker
|
||||
2. Use a combo with fallback tiers
|
||||
3. Switch to cheaper/free tier
|
||||
|
||||
**السبب:** يقوم المنبع بإرجاع حمولة SSE بينما يتوقع العميل JSON.
|
||||
### Rate Limiting
|
||||
|
||||
**الحل البديل:** استخدم `stream=true` للمكالمات السحابية المباشرة. يتضمن وقت التشغيل المحلي SSE → JSON الاحتياطي.
|
||||
**Cause:** Subscription quota exhausted.
|
||||
|
||||
### تقول السحابة إنها متصلة ولكن "مفتاح واجهة برمجة التطبيقات غير صالح"
|
||||
**Fix:**
|
||||
|
||||
1. قم بإنشاء مفتاح جديد من لوحة المعلومات المحلية (`/api/keys`)
|
||||
2. قم بتشغيل المزامنة السحابية: قم بتمكين السحابة → المزامنة الآن
|
||||
3. لا يزال بإمكان المفاتيح القديمة/غير المتزامنة إرجاع `401` على السحابة
|
||||
- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Use GLM/MiniMax as cheap backup
|
||||
|
||||
### OAuth Token Expired
|
||||
|
||||
OmniRoute auto-refreshes tokens. If issues persist:
|
||||
|
||||
1. Dashboard → Provider → Reconnect
|
||||
2. Delete and re-add the provider connection
|
||||
|
||||
---
|
||||
|
||||
## مشكلات عامل الميناء
|
||||
## Cloud Issues
|
||||
|
||||
### تظهر أداة CLI غير مثبتة
|
||||
### Cloud Sync Errors
|
||||
|
||||
1. تحقق من حقول وقت التشغيل: `curl http://localhost:20128/api/cli-tools/runtime/codex | jq`
|
||||
2. بالنسبة للوضع المحمول: استخدم هدف الصورة `runner-cli` (CLIs المجمعة)
|
||||
3. بالنسبة لوضع تثبيت المضيف: قم بتعيين `CLI_EXTRA_PATHS` وتثبيت دليل حاوية المضيف للقراءة فقط
|
||||
4. إذا تم العثور على `installed=true` و`runnable=false`: ثنائي ولكن فشل التحقق من الصحة
|
||||
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
|
||||
|
||||
### التحقق السريع من وقت التشغيل
|
||||
### Cloud `stream=false` Returns 500
|
||||
|
||||
**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
|
||||
|
||||
**Cause:** Upstream returns SSE payload while client expects JSON.
|
||||
|
||||
**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
|
||||
|
||||
### 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
|
||||
|
||||
### Quick Runtime Validation
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
@@ -91,24 +95,24 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
|
||||
|
||||
---
|
||||
|
||||
## قضايا التكلفة
|
||||
## Cost Issues
|
||||
|
||||
### ارتفاع التكاليف
|
||||
### High Costs
|
||||
|
||||
1. تحقق من إحصائيات الاستخدام في لوحة المعلومات → الاستخدام
|
||||
2. قم بتبديل النموذج الأساسي إلى GLM/MiniMax
|
||||
3. استخدم الطبقة المجانية (Gemini CLI، iFlow) للمهام غير الحرجة
|
||||
4. قم بتعيين ميزانيات التكلفة لكل مفتاح واجهة برمجة التطبيقات: لوحة المعلومات ← مفاتيح واجهة برمجة التطبيقات ← الميزانية
|
||||
1. Check usage stats in Dashboard → Usage
|
||||
2. Switch primary model to GLM/MiniMax
|
||||
3. Use free tier (Gemini CLI, iFlow) for non-critical tasks
|
||||
4. Set cost budgets per API key: Dashboard → API Keys → Budget
|
||||
|
||||
---
|
||||
|
||||
## التصحيح
|
||||
## Debugging
|
||||
|
||||
### تمكين سجلات الطلبات
|
||||
### Enable Request Logs
|
||||
|
||||
قم بتعيين `ENABLE_REQUEST_LOGS=true` في ملف `.env` الخاص بك. تظهر السجلات ضمن الدليل `logs/`.
|
||||
Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory.
|
||||
|
||||
### التحقق من صحة مقدم الخدمة
|
||||
### Check Provider Health
|
||||
|
||||
```bash
|
||||
# Health dashboard
|
||||
@@ -118,102 +122,137 @@ http://localhost:20128/dashboard/health
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
|
||||
### تخزين وقت التشغيل
|
||||
### Runtime Storage
|
||||
|
||||
- الحالة الرئيسية: `${DATA_DIR}/db.json` (المزودون، المجموعات، الأسماء المستعارة، المفاتيح، الإعدادات)
|
||||
- الاستخدام: `${DATA_DIR}/usage.json`، `${DATA_DIR}/log.txt`، `${DATA_DIR}/call_logs/`
|
||||
- سجلات الطلب: `<repo>/logs/...` (عندما `ENABLE_REQUEST_LOGS=true`)
|
||||
- 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
|
||||
|
||||
### الموفر عالق في الحالة المفتوحة
|
||||
### Provider stuck in OPEN state
|
||||
|
||||
عندما يكون قاطع دائرة الموفر مفتوحًا، يتم حظر الطلبات حتى تنتهي فترة التهدئة.
|
||||
When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
|
||||
|
||||
**الإصلاح:**
|
||||
**Fix:**
|
||||
|
||||
1. انتقل إلى **لوحة التحكم ← الإعدادات ← المرونة**
|
||||
2. تحقق من بطاقة قاطع الدائرة الكهربائية الخاصة بالمزود المتأثر
|
||||
3. انقر فوق **إعادة تعيين الكل** لمسح جميع القواطع، أو انتظر حتى تنتهي فترة التهدئة
|
||||
4. تحقق من أن الموفر متاح فعليًا قبل إعادة التعيين
|
||||
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
|
||||
|
||||
### يستمر المزود في تعطيل قاطع الدائرة
|
||||
### Provider keeps tripping the circuit breaker
|
||||
|
||||
إذا دخل مقدم الخدمة بشكل متكرر في الحالة المفتوحة:
|
||||
If a provider repeatedly enters OPEN state:
|
||||
|
||||
1. تحقق من **Dashboard → Health → Provider Health** لمعرفة نمط الفشل
|
||||
2. انتقل إلى **الإعدادات → المرونة → ملفات تعريف الموفر** وقم بزيادة حد الفشل
|
||||
3. تحقق مما إذا كان الموفر قد قام بتغيير حدود واجهة برمجة التطبيقات (API) أو طلب إعادة المصادقة
|
||||
4. قم بمراجعة القياس عن بعد لزمن الاستجابة - قد يتسبب زمن الاستجابة العالي في حدوث أعطال بسبب انتهاء المهلة
|
||||
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
|
||||
|
||||
### خطأ "نموذج غير مدعوم".
|
||||
### "Unsupported model" error
|
||||
|
||||
- تأكد من أنك تستخدم البادئة الصحيحة: `deepgram/nova-3` أو `assemblyai/best`
|
||||
- تحقق من أن الموفر متصل في **لوحة التحكم ← الموفرون**
|
||||
- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
|
||||
- Verify the provider is connected in **Dashboard → Providers**
|
||||
|
||||
### يعود النسخ فارغًا أو يفشل
|
||||
### Transcription returns empty or fails
|
||||
|
||||
- تحقق من تنسيقات الصوت المدعومة: `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`
|
||||
- التحقق من أن حجم الملف يقع ضمن حدود الموفر (عادةً أقل من 25 ميجابايت)
|
||||
- التحقق من صلاحية مفتاح API الخاص بالموفر في بطاقة المزود
|
||||
- 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
|
||||
|
||||
- **لا تظهر علامات التفكير** — تحقق مما إذا كان الموفر المستهدف يدعم التفكير وإعداد ميزانية التفكير
|
||||
- **استدعاءات الأداة** — قد تؤدي بعض ترجمات التنسيق إلى إزالة الحقول غير المدعومة؛ تحقق في وضع الملعب
|
||||
- **مطالبة النظام مفقودة** — يتعامل نظام Claude وGemini مع المطالبات بشكل مختلف؛ التحقق من إخراج الترجمة
|
||||
- ** تقوم SDK بإرجاع سلسلة أولية بدلاً من الكائن ** - تم الإصلاح في الإصدار 1.1.0: تقوم أداة معالجة الاستجابة الآن بإزالة الحقول غير القياسية (`x_groq`، `usage_breakdown`، وما إلى ذلك) التي تتسبب في فشل التحقق من صحة OpenAI SDK Pydantic
|
||||
- **GLM/ERNIE يرفض دور `system`** — تم إصلاحه في الإصدار 1.1.0: يقوم مُطبيع الدور تلقائيًا بدمج رسائل النظام في رسائل المستخدم للنماذج غير المتوافقة
|
||||
- **`developer` لم يتم التعرف على الدور** — تم إصلاحه في الإصدار 1.1.0: تم تحويله تلقائيًا إلى `system` لمقدمي الخدمات غير التابعين لـ OpenAI
|
||||
- **`json_schema` لا يعمل مع Gemini** — تم إصلاحه في الإصدار 1.1.0: `response_format` تم تحويله الآن إلى `responseMimeType` + `responseSchema` الخاص بـ Gemini\_\_
|
||||
- **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
|
||||
|
||||
### لا يتم تشغيل حد المعدل التلقائي
|
||||
### Auto rate-limit not triggering
|
||||
|
||||
- ينطبق حد المعدل التلقائي فقط على موفري مفاتيح واجهة برمجة التطبيقات (وليس OAuth/الاشتراك)
|
||||
- تحقق من أن **الإعدادات → المرونة → ملفات تعريف الموفر** تم تمكين حد المعدل التلقائي
|
||||
- تحقق مما إذا كان الموفر يعرض `429` رموز الحالة أو رؤوس `Retry-After`
|
||||
- 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
|
||||
|
||||
### ضبط التراجع الأسي
|
||||
### 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)
|
||||
|
||||
### قطيع مضاد للرعد
|
||||
### Anti-thundering herd
|
||||
|
||||
عندما تصل العديد من الطلبات المتزامنة إلى موفر محدود السعر، يستخدم OmniRoute تحديد المعدل التلقائي + mutex لإجراء تسلسل للطلبات ومنع حالات الفشل المتتالية. وهذا تلقائي لموفري مفاتيح API.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## هل مازلت عالقًا؟
|
||||
## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
|
||||
- **مشكلات GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **الهندسة المعمارية**: راجع [link](ARCHITECTURE.md) للحصول على التفاصيل الداخلية
|
||||
- **مرجع واجهة برمجة التطبيقات**: راجع [link](API_REFERENCE.md) لجميع نقاط النهاية
|
||||
- **لوحة معلومات الصحة**: تحقق من **لوحة المعلومات ← الصحة** لمعرفة حالة النظام في الوقت الفعلي
|
||||
- **المترجم**: استخدم **لوحة المعلومات ← المترجم** لتصحيح مشكلات التنسيق
|
||||
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.
|
||||
|
||||
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):
|
||||
|
||||
[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
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# دليل المستخدم
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md)
|
||||
|
||||
الدليل الكامل لتكوين مقدمي الخدمات، وإنشاء المجموعات، ودمج أدوات CLI، ونشر OmniRoute.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/USER_GUIDE.md) · 🇪🇸 [es](../es/USER_GUIDE.md) · 🇫🇷 [fr](../fr/USER_GUIDE.md) · 🇩🇪 [de](../de/USER_GUIDE.md) · 🇮🇹 [it](../it/USER_GUIDE.md) · 🇷🇺 [ru](../ru/USER_GUIDE.md) · 🇨🇳 [zh-CN](../zh-CN/USER_GUIDE.md) · 🇯🇵 [ja](../ja/USER_GUIDE.md) · 🇰🇷 [ko](../ko/USER_GUIDE.md) · 🇸🇦 [ar](../ar/USER_GUIDE.md) · 🇮🇳 [in](../in/USER_GUIDE.md) · 🇹🇭 [th](../th/USER_GUIDE.md) · 🇻🇳 [vi](../vi/USER_GUIDE.md) · 🇮🇩 [id](../id/USER_GUIDE.md) · 🇲🇾 [ms](../ms/USER_GUIDE.md) · 🇳🇱 [nl](../nl/USER_GUIDE.md) · 🇵🇱 [pl](../pl/USER_GUIDE.md) · 🇸🇪 [sv](../sv/USER_GUIDE.md) · 🇳🇴 [no](../no/USER_GUIDE.md) · 🇩🇰 [da](../da/USER_GUIDE.md) · 🇫🇮 [fi](../fi/USER_GUIDE.md) · 🇵🇹 [pt](../pt/USER_GUIDE.md) · 🇷🇴 [ro](../ro/USER_GUIDE.md) · 🇭🇺 [hu](../hu/USER_GUIDE.md) · 🇧🇬 [bg](../bg/USER_GUIDE.md) · 🇸🇰 [sk](../sk/USER_GUIDE.md) · 🇺🇦 [uk-UA](../uk-UA/USER_GUIDE.md) · 🇮🇱 [he](../he/USER_GUIDE.md) · 🇵🇭 [phi](../phi/USER_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
## جدول المحتويات
|
||||
# User Guide
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](i18n/es/USER_GUIDE.md) | 🇫🇷 [Français](i18n/fr/USER_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/USER_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/USER_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/USER_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/USER_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/USER_GUIDE.md) | 🇧🇬 [Български](i18n/bg/USER_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/USER_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/USER_GUIDE.md) | 🇮🇱 [עברית](i18n/he/USER_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/USER_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/USER_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/USER_GUIDE.md) | 🇷🇴 [Română](i18n/ro/USER_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/USER_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/USER_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/USER_GUIDE.md)
|
||||
|
||||
Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Pricing at a Glance](#-pricing-at-a-glance)
|
||||
- [Use Cases](#-use-cases)
|
||||
@@ -18,40 +22,40 @@
|
||||
|
||||
---
|
||||
|
||||
## 💰 لمحة سريعة عن الأسعار
|
||||
## 💰 Pricing at a Glance
|
||||
|
||||
| الطبقة | مقدم | التكلفة | إعادة ضبط الحصص | الأفضل لـ |
|
||||
| ---------------------------------- | ----------------------------------- | ---------------------- | ----------------------- | -------------------------------------- |
|
||||
| **💳الإشتراك** | كلود كود (برو) | 20 دولارًا شهريًا | 5 ساعات + أسبوعي | اشتركت بالفعل |
|
||||
| | الدستور الغذائي (زائد / برو) | 20-200 دولار شهريًا | 5 ساعات + أسبوعي | مستخدمي OpenAI |
|
||||
| | الجوزاء CLI | **مجاني** | 180 ألف/شهر + 1 ألف/يوم | الجميع! |
|
||||
| | جيثب مساعد الطيار | 10-19 دولارًا شهريًا | شهري | مستخدمي جيثب |
|
||||
| **🔑 مفتاح واجهة برمجة التطبيقات** | ديب سيك | الدفع لكل استخدام | لا شيء | الاستدلال الرخيص |
|
||||
| | جروك | الدفع لكل استخدام | لا شيء | الاستدلال فائق السرعة |
|
||||
| | xAI (جروك) | الدفع لكل استخدام | لا شيء | جروك 4 المنطق |
|
||||
| | ميسترال | الدفع لكل استخدام | لا شيء | النماذج التي يستضيفها الاتحاد الأوروبي |
|
||||
| | الحيرة | الدفع لكل استخدام | لا شيء | البحث المعزز |
|
||||
| | معا منظمة العفو الدولية | الدفع لكل استخدام | لا شيء | نماذج مفتوحة المصدر |
|
||||
| | الألعاب النارية منظمة العفو الدولية | الدفع لكل استخدام | لا شيء | صور التدفق السريع |
|
||||
| | المخيخ | الدفع لكل استخدام | لا شيء | سرعة على نطاق الرقاقة |
|
||||
| | كوهير | الدفع لكل استخدام | لا شيء | الأمر R+ RAG |
|
||||
| | نفيديا نيم | الدفع لكل استخدام | لا شيء | نماذج المؤسسات |
|
||||
| **💰 رخيص** | جي إل إم-4.7 | 0.6 دولار/1 مليون | يوميا 10 صباحا | نسخة احتياطية للميزانية |
|
||||
| | ميني ماكس M2.1 | 0.2 دولار/1 مليون | المتداول لمدة 5 ساعات | الخيار الأرخص |
|
||||
| | كيمي ك2 | 9 دولارات شهريًا مسطحة | 10 مليون رمز/شهر | التكلفة المتوقعة |
|
||||
| **🆓مجانًا** | اي فلو | $0 | غير محدود | 8 نماذج مجانية |
|
||||
| | كوين | $0 | غير محدود | 3 نماذج مجانية |
|
||||
| | كيرو | $0 | غير محدود | كلود مجاني |
|
||||
| Tier | Provider | Cost | Quota Reset | Best For |
|
||||
| ------------------- | ----------------- | ----------- | ---------------- | -------------------- |
|
||||
| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed |
|
||||
| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
|
||||
| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
|
||||
| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
|
||||
| **🔑 API KEY** | DeepSeek | Pay per use | None | Cheap reasoning |
|
||||
| | Groq | Pay per use | None | Ultra-fast inference |
|
||||
| | xAI (Grok) | Pay per use | None | Grok 4 reasoning |
|
||||
| | Mistral | Pay per use | None | EU-hosted models |
|
||||
| | Perplexity | Pay per use | None | Search-augmented |
|
||||
| | Together AI | Pay per use | None | Open-source models |
|
||||
| | Fireworks AI | Pay per use | None | Fast FLUX images |
|
||||
| | Cerebras | Pay per use | None | Wafer-scale speed |
|
||||
| | Cohere | Pay per use | None | Command R+ RAG |
|
||||
| | NVIDIA NIM | Pay per use | None | Enterprise models |
|
||||
| **💰 CHEAP** | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
|
||||
| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
|
||||
| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
|
||||
| **🆓 FREE** | iFlow | $0 | Unlimited | 8 models free |
|
||||
| | Qwen | $0 | Unlimited | 3 models free |
|
||||
| | Kiro | $0 | Unlimited | Claude free |
|
||||
|
||||
**💡 نصيحة احترافية:** ابدأ مع مجموعة Gemini CLI (180 ألفًا مجانًا شهريًا) + مجموعة iFlow (مجانية غير محدودة) = تكلفة 0 دولار!
|
||||
**💡 Pro Tip:** Start with Gemini CLI (180K free/month) + iFlow (unlimited free) combo = $0 cost!
|
||||
|
||||
---
|
||||
|
||||
## 🎯 حالات الاستخدام
|
||||
## 🎯 Use Cases
|
||||
|
||||
### الحالة 1: "لدي اشتراك Claude Pro"
|
||||
### Case 1: "I have Claude Pro subscription"
|
||||
|
||||
**المشكلة:** تنتهي صلاحية الحصة غير المستخدمة، وحدود المعدل أثناء عملية الترميز المكثف
|
||||
**Problem:** Quota expires unused, rate limits during heavy coding
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
@@ -63,9 +67,9 @@ Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### الحالة 2: "أريد تكلفة صفرية"
|
||||
### Case 2: "I want zero cost"
|
||||
|
||||
**المشكلة:** لا أستطيع تحمل تكلفة الاشتراكات، وتحتاج إلى ترميز يعتمد على الذكاء الاصطناعي
|
||||
**Problem:** Can't afford subscriptions, need reliable AI coding
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
@@ -77,9 +81,9 @@ Monthly cost: $0
|
||||
Quality: Production-ready models
|
||||
```
|
||||
|
||||
### الحالة 3: "أحتاج إلى تشفير على مدار 24 ساعة طوال أيام الأسبوع، دون انقطاع"
|
||||
### Case 3: "I need 24/7 coding, no interruptions"
|
||||
|
||||
**المشكلة:** المواعيد النهائية، لا أستطيع تحمل فترات التوقف عن العمل
|
||||
**Problem:** Deadlines, can't afford downtime
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
@@ -93,9 +97,9 @@ Result: 5 layers of fallback = zero downtime
|
||||
Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
|
||||
```
|
||||
|
||||
### الحالة 4: "أريد ذكاءً اصطناعيًا مجانيًا في OpenClaw"
|
||||
### Case 4: "I want FREE AI in OpenClaw"
|
||||
|
||||
**المشكلة:** تحتاج إلى مساعد الذكاء الاصطناعي في تطبيقات المراسلة، مجانًا تمامًا
|
||||
**Problem:** Need AI assistant in messaging apps, completely free
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
@@ -109,11 +113,11 @@ Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
|
||||
---
|
||||
|
||||
## 📖 إعداد الموفر
|
||||
## 📖 Provider Setup
|
||||
|
||||
### 🔐 مقدمي الاشتراكات
|
||||
### 🔐 Subscription Providers
|
||||
|
||||
#### كلود كود (برو/ماكس)
|
||||
#### Claude Code (Pro/Max)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Claude Code
|
||||
@@ -126,7 +130,7 @@ Models:
|
||||
cc/claude-haiku-4-5-20251001
|
||||
```
|
||||
|
||||
**نصيحة احترافية:** استخدم Opus للمهام المعقدة، وSonnet للسرعة. OmniRoute يتتبع الحصة لكل نموذج!
|
||||
**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model!
|
||||
|
||||
#### OpenAI Codex (Plus/Pro)
|
||||
|
||||
@@ -140,7 +144,7 @@ Models:
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Gemini CLI (180 ألفًا شهريًا مجانًا!)
|
||||
#### Gemini CLI (FREE 180K/month!)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Gemini CLI
|
||||
@@ -152,9 +156,9 @@ Models:
|
||||
gc/gemini-2.5-pro
|
||||
```
|
||||
|
||||
**أفضل قيمة:** طبقة مجانية ضخمة! استخدم هذا قبل المستويات المدفوعة.
|
||||
**Best Value:** Huge free tier! Use this before paid tiers.
|
||||
|
||||
#### مساعد جيثب
|
||||
#### GitHub Copilot
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect GitHub
|
||||
@@ -167,33 +171,33 @@ Models:
|
||||
gh/gemini-3-pro
|
||||
```
|
||||
|
||||
### 💰 مقدمو خدمات رخيصون
|
||||
### 💰 Cheap Providers
|
||||
|
||||
#### GLM-4.7 (إعادة التعيين اليومي، 0.6 دولار/1 مليون)
|
||||
#### GLM-4.7 (Daily reset, $0.6/1M)
|
||||
|
||||
1. قم بالتسجيل: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. احصل على مفتاح API من خطة الترميز
|
||||
3. لوحة المعلومات → إضافة مفتاح واجهة برمجة التطبيقات: الموفر: `glm`، مفتاح واجهة برمجة التطبيقات: `your-key`
|
||||
1. Sign up: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. Get API key from Coding Plan
|
||||
3. Dashboard → Add API Key: Provider: `glm`, API Key: `your-key`
|
||||
|
||||
**الاستخدام:** `glm/glm-4.7` — **نصيحة احترافية:** توفر خطة البرمجة حصة 3× بتكلفة 1/7! إعادة الضبط يوميًا الساعة 10:00 صباحًا.
|
||||
**Use:** `glm/glm-4.7` — **Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM.
|
||||
|
||||
#### MiniMax M2.1 (إعادة الضبط لمدة 5 ساعات، 0.20 دولار/1 مليون)
|
||||
#### MiniMax M2.1 (5h reset, $0.20/1M)
|
||||
|
||||
1. قم بالتسجيل: [MiniMax](https://www.minimax.io/)
|
||||
2. احصل على مفتاح API → لوحة المعلومات → إضافة مفتاح API
|
||||
1. Sign up: [MiniMax](https://www.minimax.io/)
|
||||
2. Get API key → Dashboard → Add API Key
|
||||
|
||||
**الاستخدام:** `minimax/MiniMax-M2.1` — **نصيحة احترافية:** الخيار الأرخص للسياق الطويل (مليون رمز)!
|
||||
**Use:** `minimax/MiniMax-M2.1` — **Pro Tip:** Cheapest option for long context (1M tokens)!
|
||||
|
||||
#### كيمي K2 (شقة بقيمة 9 دولارات في الشهر)
|
||||
#### Kimi K2 ($9/month flat)
|
||||
|
||||
1. الاشتراك: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. احصل على مفتاح API → لوحة المعلومات → إضافة مفتاح API
|
||||
1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. Get API key → Dashboard → Add API Key
|
||||
|
||||
**الاستخدام:** `kimi/kimi-latest` — **نصيحة احترافية:** سعر ثابت قدره 9 دولارات شهريًا مقابل 10 ملايين رمز مميز = 0.90 دولارًا أمريكيًا/التكلفة الفعلية لمليون واحد!
|
||||
**Use:** `kimi/kimi-latest` — **Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost!
|
||||
|
||||
### 🆓 مقدمي الخدمة مجانًا
|
||||
### 🆓 FREE Providers
|
||||
|
||||
#### iFlow (8 نماذج مجانية)
|
||||
#### iFlow (8 FREE models)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
@@ -201,7 +205,7 @@ Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
|
||||
```
|
||||
|
||||
#### كوين (3 موديلات مجانية)
|
||||
#### Qwen (3 FREE models)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
@@ -209,7 +213,7 @@ Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
|
||||
```
|
||||
|
||||
#### كيرو (كلود فري)
|
||||
#### Kiro (Claude FREE)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
|
||||
@@ -219,9 +223,9 @@ Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
|
||||
|
||||
---
|
||||
|
||||
## 🎨 المجموعات
|
||||
## 🎨 Combos
|
||||
|
||||
### مثال 1: زيادة الاشتراك إلى الحد الأقصى → النسخ الاحتياطي الرخيص
|
||||
### Example 1: Maximize Subscription → Cheap Backup
|
||||
|
||||
```
|
||||
Dashboard → Combos → Create New
|
||||
@@ -235,7 +239,7 @@ Models:
|
||||
Use in CLI: premium-coding
|
||||
```
|
||||
|
||||
### المثال 2: مجاني فقط (بدون تكلفة)
|
||||
### Example 2: Free-Only (Zero Cost)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
@@ -249,9 +253,9 @@ Cost: $0 forever!
|
||||
|
||||
---
|
||||
|
||||
## 🔧 تكامل CLI
|
||||
## 🔧 CLI Integration
|
||||
|
||||
### بيئة تطوير متكاملة للمؤشر
|
||||
### Cursor IDE
|
||||
|
||||
```
|
||||
Settings → Models → Advanced:
|
||||
@@ -260,9 +264,9 @@ Settings → Models → Advanced:
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
### كلود كود
|
||||
### Claude Code
|
||||
|
||||
تحرير `~/.claude/config.json`:
|
||||
Edit `~/.claude/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -271,7 +275,7 @@ Settings → Models → Advanced:
|
||||
}
|
||||
```
|
||||
|
||||
### كوديكس سطر الأوامر
|
||||
### Codex CLI
|
||||
|
||||
```bash
|
||||
export OPENAI_BASE_URL="http://localhost:20128"
|
||||
@@ -281,7 +285,7 @@ codex "your prompt"
|
||||
|
||||
### OpenClaw
|
||||
|
||||
تحرير `~/.openclaw/openclaw.json`:
|
||||
Edit `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -303,9 +307,9 @@ codex "your prompt"
|
||||
}
|
||||
```
|
||||
|
||||
**أو استخدم لوحة المعلومات:** أدوات CLI → OpenClaw → التكوين التلقائي
|
||||
**Or use Dashboard:** CLI Tools → OpenClaw → Auto-config
|
||||
|
||||
### كلاين / متابعة / RooCode
|
||||
### Cline / Continue / RooCode
|
||||
|
||||
```
|
||||
Provider: OpenAI Compatible
|
||||
@@ -316,9 +320,28 @@ Model: cc/claude-opus-4-6
|
||||
|
||||
---
|
||||
|
||||
## 🚀 النشر
|
||||
## 🚀 Deployment
|
||||
|
||||
### نشر VPS
|
||||
### Global npm install (Recommended)
|
||||
|
||||
```bash
|
||||
npm install -g omniroute
|
||||
|
||||
# Create config directory
|
||||
mkdir -p ~/.omniroute
|
||||
|
||||
# Create .env file (see .env.example)
|
||||
cp .env.example ~/.omniroute/.env
|
||||
|
||||
# Start server
|
||||
omniroute
|
||||
# Or with custom port:
|
||||
omniroute --port 3000
|
||||
```
|
||||
|
||||
The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
|
||||
|
||||
### VPS Deployment
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
@@ -337,7 +360,44 @@ npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### عامل الميناء
|
||||
### PM2 Deployment (Low Memory)
|
||||
|
||||
For servers with limited RAM, use the memory limit option:
|
||||
|
||||
```bash
|
||||
# With 512MB limit (default)
|
||||
pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or with custom memory limit
|
||||
OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or using ecosystem.config.js
|
||||
pm2 start ecosystem.config.js
|
||||
```
|
||||
|
||||
Create `ecosystem.config.js`:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "omniroute",
|
||||
script: "npm",
|
||||
args: "start",
|
||||
env: {
|
||||
NODE_ENV: "production",
|
||||
OMNIROUTE_MEMORY_MB: "512",
|
||||
JWT_SECRET: "your-secret",
|
||||
INITIAL_PASSWORD: "your-password",
|
||||
},
|
||||
node_args: "--max-old-space-size=512",
|
||||
max_memory_restart: "300M",
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build image (default = runner-cli with codex/claude/droid preinstalled)
|
||||
@@ -347,81 +407,84 @@ docker build -t omniroute:cli .
|
||||
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
|
||||
```
|
||||
|
||||
بالنسبة للوضع المدمج مع المضيف مع ثنائيات CLI، راجع قسم Docker في المستندات الرئيسية.
|
||||
For host-integrated mode with CLI binaries, see the Docker section in the main docs.
|
||||
|
||||
### متغيرات البيئة
|
||||
### Environment Variables
|
||||
|
||||
| متغير | الافتراضي | الوصف |
|
||||
| --------------------- | ------------------------------------ | ---------------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | سر توقيع JWT (**تغيير في الإنتاج**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | كلمة المرور الأولى لتسجيل الدخول |
|
||||
| `DATA_DIR` | `~/.omniroute` | دليل البيانات (ديسيبل، الاستخدام، السجلات) |
|
||||
| `PORT` | الإطار الافتراضي | منفذ الخدمة (`20128` في الأمثلة) |
|
||||
| `HOSTNAME` | الإطار الافتراضي | ربط المضيف (إعدادات Docker الافتراضية هي `0.0.0.0`) |
|
||||
| `NODE_ENV` | وقت التشغيل الافتراضي | قم بتعيين `production` للنشر |
|
||||
| `BASE_URL` | `http://localhost:20128` | عنوان URL الأساسي الداخلي من جانب الخادم |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | عنوان URL الأساسي لنقطة نهاية المزامنة السحابية |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | سر HMAC لمفاتيح API التي تم إنشاؤها |
|
||||
| `REQUIRE_API_KEY` | `false` | فرض مفتاح Bearer API على `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | تمكين سجلات الطلب/الاستجابة |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | فرض ملف تعريف ارتباط المصادقة `Secure` (خلف الوكيل العكسي HTTPS) |
|
||||
| Variable | Default | Description |
|
||||
| ------------------------- | ------------------------------------ | ------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | First login password |
|
||||
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
|
||||
| `PORT` | framework default | Service port (`20128` in examples) |
|
||||
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
|
||||
| `NODE_ENV` | runtime default | Set `production` for deploy |
|
||||
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
|
||||
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB |
|
||||
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
|
||||
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
|
||||
|
||||
للحصول على مرجع متغير البيئة الكامل، راجع [README](../README.md).
|
||||
For the full environment variable reference, see the [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
## 📊 الموديلات المتوفرة
|
||||
## 📊 Available Models
|
||||
|
||||
<details>
|
||||
<summary><b>عرض جميع الموديلات المتاحة</b></summary>
|
||||
<summary><b>View all available models</b></summary>
|
||||
|
||||
**كود كلود (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**المخطوطة (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`، `cx/gpt-5.1-codex-max`
|
||||
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** — مجانًا: `gc/gemini-3-flash-preview`، `gc/gemini-2.5-pro`
|
||||
**Gemini CLI (`gc/`)** — FREE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
|
||||
|
||||
**مساعد GitHub (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
|
||||
**GLM (`glm/`)** — 0.6 دولار/1 مليون: `glm/glm-4.7`
|
||||
**GLM (`glm/`)** — $0.6/1M: `glm/glm-4.7`
|
||||
|
||||
**ميني ماكس (`minimax/`)** — 0.2 دولار/1 مليون: `minimax/MiniMax-M2.1`
|
||||
**MiniMax (`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** — مجانًا: `if/kimi-k2-thinking`، `if/qwen3-coder-plus`، `if/deepseek-r1`
|
||||
**iFlow (`if/`)** — FREE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
|
||||
|
||||
**كوين (`qw/`)** — مجانًا: `qw/qwen3-coder-plus`، `qw/qwen3-coder-flash`
|
||||
**Qwen (`qw/`)** — FREE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
|
||||
|
||||
**كيرو (`kr/`)** — مجانًا: `kr/claude-sonnet-4.5`، `kr/claude-haiku-4.5`
|
||||
**Kiro (`kr/`)** — FREE: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
|
||||
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`، `ds/deepseek-reasoner`
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner`
|
||||
|
||||
** جروك (`groq/`)**: `groq/llama-3.3-70b-versatile`، `groq/llama-4-maverick-17b-128e-instruct`
|
||||
**Groq (`groq/`)**: `groq/llama-3.3-70b-versatile`, `groq/llama-4-maverick-17b-128e-instruct`
|
||||
|
||||
**xAI (`xai/`)**: `xai/grok-4`، `xai/grok-4-0709-fast-reasoning`، `xai/grok-code-mini`
|
||||
**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini`
|
||||
|
||||
**ميسترال (`mistral/`)**: `mistral/mistral-large-2501`، `mistral/codestral-2501`
|
||||
**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501`
|
||||
|
||||
**الحيرة (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
**Perplexity (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
|
||||
** معًا الذكاء الاصطناعي (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
**Together AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
|
||||
**الذكاء الاصطناعي للألعاب النارية (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
|
||||
** سيريبراس (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
|
||||
**الترابط (`cohere/`)**: `cohere/command-r-plus-08-2024`
|
||||
**Cohere (`cohere/`)**: `cohere/command-r-plus-08-2024`
|
||||
|
||||
** نفيديا نيم (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct`
|
||||
**NVIDIA NIM (`nvidia/`)**: `nvidia/nvidia/llama-3.3-70b-instruct`
|
||||
|
||||
</details>
|
||||
|
||||
---
|
||||
|
||||
## 🧩 ميزات متقدمة
|
||||
## 🧩 Advanced Features
|
||||
|
||||
### نماذج مخصصة
|
||||
### Custom Models
|
||||
|
||||
أضف أي معرف نموذج إلى أي مزود دون انتظار تحديث التطبيق:
|
||||
Add any model ID to any provider without waiting for an app update:
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
@@ -433,11 +496,11 @@ curl -X POST http://localhost:20128/api/provider-models \
|
||||
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
|
||||
```
|
||||
|
||||
أو استخدم لوحة المعلومات: **المزودون → [الموفر] → النماذج المخصصة**.
|
||||
Or use Dashboard: **Providers → [Provider] → Custom Models**.
|
||||
|
||||
### مسارات موفر مخصصة
|
||||
### Dedicated Provider Routes
|
||||
|
||||
توجيه الطلبات مباشرة إلى موفر محدد مع التحقق من صحة النموذج:
|
||||
Route requests directly to a specific provider with model validation:
|
||||
|
||||
```bash
|
||||
POST http://localhost:20128/v1/providers/openai/chat/completions
|
||||
@@ -445,9 +508,9 @@ POST http://localhost:20128/v1/providers/openai/embeddings
|
||||
POST http://localhost:20128/v1/providers/fireworks/images/generations
|
||||
```
|
||||
|
||||
تتم إضافة بادئة الموفر تلقائيًا في حالة فقدانها. تُرجع النماذج غير المتطابقة `400`.
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
### تكوين وكيل الشبكة
|
||||
### Network Proxy Configuration
|
||||
|
||||
```bash
|
||||
# Set global proxy
|
||||
@@ -463,76 +526,76 @@ curl -X POST http://localhost:20128/api/settings/proxy/test \
|
||||
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
|
||||
```
|
||||
|
||||
**الأسبقية:** خاص بالمفتاح ← خاص بالسرد والسرد ← خاص بالموفر ← عالمي ← البيئة.
|
||||
**Precedence:** Key-specific → Combo-specific → Provider-specific → Global → Environment.
|
||||
|
||||
### واجهة برمجة تطبيقات الكتالوج النموذجي
|
||||
### Model Catalog API
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/api/models/catalog
|
||||
```
|
||||
|
||||
إرجاع النماذج المجمعة حسب الموفر مع الأنواع (`chat`، `embedding`، `image`).
|
||||
Returns models grouped by provider with types (`chat`, `embedding`, `image`).
|
||||
|
||||
### المزامنة السحابية
|
||||
### Cloud Sync
|
||||
|
||||
- موفري المزامنة والمجموعات والإعدادات عبر الأجهزة
|
||||
- مزامنة الخلفية التلقائية مع انتهاء المهلة + الفشل السريع
|
||||
- تفضيل جانب الخادم `BASE_URL`/`CLOUD_URL` في الإنتاج
|
||||
- Sync providers, combos, and settings across devices
|
||||
- Automatic background sync with timeout + fail-fast
|
||||
- Prefer server-side `BASE_URL`/`CLOUD_URL` in production
|
||||
|
||||
### LLM Gateway Intelligence (المرحلة 9)
|
||||
### LLM Gateway Intelligence (Phase 9)
|
||||
|
||||
- **ذاكرة التخزين المؤقت الدلالية** — ذاكرة تخزين مؤقت تلقائية غير متدفقة، درجة الحرارة = 0 استجابات (تجاوز باستخدام `X-OmniRoute-No-Cache: true`)
|
||||
- **صلاحية الطلب** — إلغاء تكرار الطلبات خلال 5 ثوانٍ عبر رأس `Idempotency-Key` أو `X-Request-Id`
|
||||
- **تتبع التقدم** — الاشتراك في أحداث SSE `event: progress` عبر رأس `X-OmniRoute-Progress: true`
|
||||
- **Semantic Cache** — Auto-caches non-streaming, temperature=0 responses (bypass with `X-OmniRoute-No-Cache: true`)
|
||||
- **Request Idempotency** — Deduplicates requests within 5s via `Idempotency-Key` or `X-Request-Id` header
|
||||
- **Progress Tracking** — Opt-in SSE `event: progress` events via `X-OmniRoute-Progress: true` header
|
||||
|
||||
---
|
||||
|
||||
### ملعب المترجم
|
||||
### Translator Playground
|
||||
|
||||
الوصول عبر **لوحة المعلومات → المترجم**. تصحيح الأخطاء وتصور كيفية قيام OmniRoute بترجمة طلبات واجهة برمجة التطبيقات (API) بين مقدمي الخدمة.
|
||||
Access via **Dashboard → Translator**. Debug and visualize how OmniRoute translates API requests between providers.
|
||||
|
||||
| الوضع | الغرض |
|
||||
| -------------------- | ----------------------------------------------------------------------------- |
|
||||
| **ساحة اللعب** | حدد تنسيقات المصدر/الهدف، والصق طلبًا، وشاهد المخرجات المترجمة على الفور |
|
||||
| ** اختبار الدردشة ** | أرسل رسائل الدردشة المباشرة من خلال الوكيل وافحص دورة الطلب/الاستجابة الكاملة |
|
||||
| ** مقعد الاختبار ** | قم بإجراء اختبارات مجمعة عبر مجموعات تنسيقات متعددة للتحقق من صحة الترجمة |
|
||||
| **مراقبة حية** | شاهد الترجمات في الوقت الفعلي أثناء تدفق الطلبات عبر الوكيل |
|
||||
| Mode | Purpose |
|
||||
| ---------------- | -------------------------------------------------------------------------------------- |
|
||||
| **Playground** | Select source/target formats, paste a request, and see the translated output instantly |
|
||||
| **Chat Tester** | Send live chat messages through the proxy and inspect the full request/response cycle |
|
||||
| **Test Bench** | Run batch tests across multiple format combinations to verify translation correctness |
|
||||
| **Live Monitor** | Watch real-time translations as requests flow through the proxy |
|
||||
|
||||
**حالات الاستخدام:**
|
||||
**Use cases:**
|
||||
|
||||
- تصحيح سبب فشل مجموعة محددة من العميل/الموفر
|
||||
- التحقق من ترجمة علامات التفكير واستدعاءات الأدوات ومطالبات النظام بشكل صحيح
|
||||
- مقارنة اختلافات التنسيق بين تنسيقات OpenAI وClaude وGemini وResponsions API
|
||||
- Debug why a specific client/provider combination fails
|
||||
- Verify that thinking tags, tool calls, and system prompts translate correctly
|
||||
- Compare format differences between OpenAI, Claude, Gemini, and Responses API formats
|
||||
|
||||
---
|
||||
|
||||
### استراتيجيات التوجيه
|
||||
### Routing Strategies
|
||||
|
||||
قم بالتكوين عبر **لوحة المعلومات → الإعدادات → التوجيه**.
|
||||
Configure via **Dashboard → Settings → Routing**.
|
||||
|
||||
| استراتيجية | الوصف |
|
||||
| ------------------------ | ---------------------------------------------------------------------------------------- |
|
||||
| ** املأ أولا ** | يستخدم الحسابات بترتيب الأولوية — يعالج الحساب الأساسي جميع الطلبات حتى تصبح غير متاحة |
|
||||
| ** راوند روبن ** | للتنقل عبر جميع الحسابات بحد ثابت قابل للتكوين (الافتراضي: 3 مكالمات لكل حساب) |
|
||||
| **P2C (قوة الاختيارين)** | يختار حسابين عشوائيين ويوجهك إلى الحساب الأكثر صحة - الأرصدة محملة بالوعي الصحي |
|
||||
| **عشوائي** | تحديد حساب عشوائيًا لكل طلب باستخدام خلط Fisher-Yates |
|
||||
| **الأقل استخدامًا** | التوجيهات إلى الحساب ذو الطابع الزمني الأقدم `lastUsedAt`، مع توزيع حركة المرور بالتساوي |
|
||||
| **التكلفة الأمثل** | التوجيهات إلى الحساب ذي أقل قيمة أولوية، مع تحسين موفري الخدمة الأقل تكلفة |
|
||||
| Strategy | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------ |
|
||||
| **Fill First** | Uses accounts in priority order — primary account handles all requests until unavailable |
|
||||
| **Round Robin** | Cycles through all accounts with a configurable sticky limit (default: 3 calls per account) |
|
||||
| **P2C (Power of Two Choices)** | Picks 2 random accounts and routes to the healthier one — balances load with awareness of health |
|
||||
| **Random** | Randomly selects an account for each request using Fisher-Yates shuffle |
|
||||
| **Least Used** | Routes to the account with the oldest `lastUsedAt` timestamp, distributing traffic evenly |
|
||||
| **Cost Optimized** | Routes to the account with the lowest priority value, optimizing for lowest-cost providers |
|
||||
|
||||
#### الأسماء المستعارة لنموذج البدل
|
||||
#### Wildcard Model Aliases
|
||||
|
||||
قم بإنشاء أنماط أحرف البدل لإعادة تعيين أسماء النماذج:
|
||||
Create wildcard patterns to remap model names:
|
||||
|
||||
```
|
||||
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
|
||||
Pattern: gpt-* → Target: gh/gpt-5.1-codex
|
||||
```
|
||||
|
||||
تدعم أحرف البدل `*` (أي أحرف) و`?` (حرف واحد).
|
||||
Wildcards support `*` (any characters) and `?` (single character).
|
||||
|
||||
#### سلاسل احتياطية
|
||||
#### Fallback Chains
|
||||
|
||||
تحديد السلاسل الاحتياطية العالمية التي تنطبق على جميع الطلبات:
|
||||
Define global fallback chains that apply across all requests:
|
||||
|
||||
```
|
||||
Chain: production-fallback
|
||||
@@ -543,46 +606,46 @@ Chain: production-fallback
|
||||
|
||||
---
|
||||
|
||||
### المرونة وقواطع الدائرة
|
||||
### Resilience & Circuit Breakers
|
||||
|
||||
قم بالتكوين عبر **لوحة المعلومات → الإعدادات → المرونة**.
|
||||
Configure via **Dashboard → Settings → Resilience**.
|
||||
|
||||
تطبق OmniRoute المرونة على مستوى المزود من خلال أربعة مكونات:
|
||||
OmniRoute implements provider-level resilience with four components:
|
||||
|
||||
1. **ملفات تعريف الموفر** — التكوين لكل موفر لـ:
|
||||
- عتبة الفشل (كم عدد حالات الفشل قبل الفتح)
|
||||
- مدة التهدئة
|
||||
- حساسية الكشف عن حد المعدل
|
||||
- معلمات التراجع الأسي
|
||||
1. **Provider Profiles** — Per-provider configuration for:
|
||||
- Failure threshold (how many failures before opening)
|
||||
- Cooldown duration
|
||||
- Rate limit detection sensitivity
|
||||
- Exponential backoff parameters
|
||||
|
||||
2. **حدود المعدل القابلة للتحرير** — الإعدادات الافتراضية على مستوى النظام قابلة للتكوين في لوحة المعلومات:
|
||||
- **الطلبات في الدقيقة (RPM)** — الحد الأقصى للطلبات في الدقيقة لكل حساب
|
||||
- **الحد الأدنى للوقت بين الطلبات** — الحد الأدنى للفجوة بالمللي ثانية بين الطلبات
|
||||
- **الحد الأقصى للطلبات المتزامنة** — الحد الأقصى للطلبات المتزامنة لكل حساب
|
||||
- انقر **تحرير** للتعديل، ثم **حفظ** أو **إلغاء**. تستمر القيم عبر واجهة برمجة تطبيقات المرونة.
|
||||
2. **Editable Rate Limits** — System-level defaults configurable in the dashboard:
|
||||
- **Requests Per Minute (RPM)** — Maximum requests per minute per account
|
||||
- **Min Time Between Requests** — Minimum gap in milliseconds between requests
|
||||
- **Max Concurrent Requests** — Maximum simultaneous requests per account
|
||||
- Click **Edit** to modify, then **Save** or **Cancel**. Values persist via the resilience API.
|
||||
|
||||
3. **قاطع الدائرة** — يتتبع حالات الفشل لكل مزود ويفتح الدائرة تلقائيًا عند الوصول إلى الحد الأدنى:
|
||||
- **مغلق** (صحي) — تتدفق الطلبات بشكل طبيعي
|
||||
- **مفتوح** — تم حظر الموفر مؤقتًا بعد الفشل المتكرر
|
||||
- **HALF_OPEN** — اختبار ما إذا كان الموفر قد استعاد عافيته
|
||||
3. **Circuit Breaker** — Tracks failures per provider and automatically opens the circuit when a threshold is reached:
|
||||
- **CLOSED** (Healthy) — Requests flow normally
|
||||
- **OPEN** — Provider is temporarily blocked after repeated failures
|
||||
- **HALF_OPEN** — Testing if provider has recovered
|
||||
|
||||
4. **السياسات والمعرفات المقفلة** — تعرض حالة قاطع الدائرة والمعرفات المقفلة مع إمكانية إلغاء القفل بالقوة.
|
||||
4. **Policies & Locked Identifiers** — Shows circuit breaker status and locked identifiers with force-unlock capability.
|
||||
|
||||
5. **الاكتشاف التلقائي لحدود المعدل** — يراقب الرؤوس `429` و`Retry-After` لتجنب الوصول إلى حدود معدل الموفر بشكل استباقي.
|
||||
5. **Rate Limit Auto-Detection** — Monitors `429` and `Retry-After` headers to proactively avoid hitting provider rate limits.
|
||||
|
||||
**نصيحة احترافية:** استخدم زر **إعادة تعيين الكل** لمسح جميع قواطع الدائرة وفترات التباطؤ عندما يتعافى المزود من انقطاع الخدمة.
|
||||
**Pro Tip:** Use **Reset All** button to clear all circuit breakers and cooldowns when a provider recovers from an outage.
|
||||
|
||||
---
|
||||
|
||||
### تصدير / استيراد قاعدة البيانات
|
||||
### Database Export / Import
|
||||
|
||||
إدارة النسخ الاحتياطية لقاعدة البيانات في **لوحة المعلومات → الإعدادات → النظام والتخزين**.
|
||||
Manage database backups in **Dashboard → Settings → System & Storage**.
|
||||
|
||||
| العمل | الوصف |
|
||||
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **تصدير قاعدة البيانات** | يقوم بتنزيل قاعدة بيانات SQLite الحالية كملف `.sqlite` |
|
||||
| **تصدير الكل (.tar.gz)** | تنزيل أرشيف نسخ احتياطي كامل بما في ذلك: قاعدة البيانات، والإعدادات، والمجموعات، واتصالات الموفر (بدون بيانات اعتماد)، وبيانات تعريف مفتاح API |
|
||||
| **استيراد قاعدة البيانات** | قم بتحميل ملف `.sqlite` لاستبدال قاعدة البيانات الحالية. يتم إنشاء نسخة احتياطية للاستيراد المسبق تلقائيًا |
|
||||
| Action | Description |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Export Database** | Downloads the current SQLite database as a `.sqlite` file |
|
||||
| **Export All (.tar.gz)** | Downloads a full backup archive including: database, settings, combos, provider connections (no credentials), API key metadata |
|
||||
| **Import Database** | Upload a `.sqlite` file to replace the current database. A pre-import backup is automatically created |
|
||||
|
||||
```bash
|
||||
# API: Export database
|
||||
@@ -596,38 +659,38 @@ curl -X POST http://localhost:20128/api/db-backups/import \
|
||||
-F "file=@backup.sqlite"
|
||||
```
|
||||
|
||||
**التحقق من صحة الاستيراد:** يتم التحقق من صحة الملف المستورد للتأكد من سلامته (فحص براغما SQLite)، والجداول المطلوبة (`provider_connections`، `provider_nodes`، `combos`، `api_keys`)، والحجم (100 ميجابايت كحد أقصى).
|
||||
**Import Validation:** The imported file is validated for integrity (SQLite pragma check), required tables (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), and size (max 100MB).
|
||||
|
||||
**حالات الاستخدام:**
|
||||
**Use Cases:**
|
||||
|
||||
- ترحيل OmniRoute بين الأجهزة
|
||||
- إنشاء نسخ احتياطية خارجية للتعافي من الكوارث
|
||||
- مشاركة التكوينات بين أعضاء الفريق (تصدير الكل → مشاركة الأرشيف)
|
||||
- Migrate OmniRoute between machines
|
||||
- Create external backups for disaster recovery
|
||||
- Share configurations between team members (export all → share archive)
|
||||
|
||||
---
|
||||
|
||||
### لوحة تحكم الإعدادات
|
||||
### Settings Dashboard
|
||||
|
||||
يتم تنظيم صفحة الإعدادات في 5 علامات تبويب لسهولة التنقل:
|
||||
The settings page is organized into 5 tabs for easy navigation:
|
||||
|
||||
| علامة التبويب | المحتويات |
|
||||
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **الأمن** | إعدادات تسجيل الدخول/كلمة المرور، والتحكم في الوصول إلى IP، ومصادقة API لـ `/models`، وحظر الموفر |
|
||||
| **التوجيه** | استراتيجية التوجيه العالمية (6 خيارات)، والأسماء المستعارة لنماذج أحرف البدل، والسلاسل الاحتياطية، وافتراضيات التحرير والسرد |
|
||||
| **المرونة** | ملفات تعريف الموفر، وحدود الأسعار القابلة للتحرير، وحالة قاطع الدائرة، والسياسات والمعرفات المقفلة |
|
||||
| **الذكاء الاصطناعي** | تكوين ميزانية التفكير، والحقن الفوري للنظام العالمي، وإحصائيات ذاكرة التخزين المؤقت السريعة |
|
||||
| **متقدم** | تكوين الوكيل العالمي (HTTP/SOCKS5) |
|
||||
| Tab | Contents |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| **Security** | Login/Password settings, IP Access Control, API auth for `/models`, and Provider Blocking |
|
||||
| **Routing** | Global routing strategy (6 options), wildcard model aliases, fallback chains, combo defaults |
|
||||
| **Resilience** | Provider profiles, editable rate limits, circuit breaker status, policies & locked identifiers |
|
||||
| **AI** | Thinking budget configuration, global system prompt injection, prompt cache stats |
|
||||
| **Advanced** | Global proxy configuration (HTTP/SOCKS5) |
|
||||
|
||||
---
|
||||
|
||||
### إدارة التكاليف والميزانية
|
||||
### Costs & Budget Management
|
||||
|
||||
الوصول عبر **لوحة التحكم ← التكاليف**.
|
||||
Access via **Dashboard → Costs**.
|
||||
|
||||
| علامة التبويب | الغرض |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------ |
|
||||
| **الميزانية** | قم بتعيين حدود الإنفاق لكل مفتاح API باستخدام ميزانيات يومية/أسبوعية/شهرية وتتبع في الوقت الفعلي |
|
||||
| **التسعير** | عرض وتحرير إدخالات تسعير النموذج - التكلفة لكل ألف رمز إدخال/إخراج لكل مزود |
|
||||
| Tab | Purpose |
|
||||
| ----------- | ---------------------------------------------------------------------------------------- |
|
||||
| **Budget** | Set spending limits per API key with daily/weekly/monthly budgets and real-time tracking |
|
||||
| **Pricing** | View and edit model pricing entries — cost per 1K input/output tokens per provider |
|
||||
|
||||
```bash
|
||||
# API: Set a budget
|
||||
@@ -639,13 +702,13 @@ curl -X POST http://localhost:20128/api/usage/budget \
|
||||
curl http://localhost:20128/api/usage/budget
|
||||
```
|
||||
|
||||
**تتبع التكلفة:** يقوم كل طلب بتسجيل استخدام الرمز المميز وحساب التكلفة باستخدام جدول التسعير. عرض التفاصيل في **لوحة المعلومات → الاستخدام** حسب الموفر والطراز ومفتاح واجهة برمجة التطبيقات.
|
||||
**Cost Tracking:** Every request logs token usage and calculates cost using the pricing table. View breakdowns in **Dashboard → Usage** by provider, model, and API key.
|
||||
|
||||
---
|
||||
|
||||
### النسخ الصوتي
|
||||
### Audio Transcription
|
||||
|
||||
يدعم OmniRoute النسخ الصوتي عبر نقطة النهاية المتوافقة مع OpenAI:
|
||||
OmniRoute supports audio transcription via the OpenAI-compatible endpoint:
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
@@ -659,40 +722,92 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
الموفرون المتاحون: **Deepgram** (`deepgram/`)، **AssemblyAI** (`assemblyai/`).
|
||||
Available providers: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
|
||||
|
||||
تنسيقات الصوت المدعومة: `mp3`، `wav`، `m4a`، `flac`، `ogg`، `webm`.
|
||||
Supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
### استراتيجيات موازنة التحرير والسرد
|
||||
### Combo Balancing Strategies
|
||||
|
||||
قم بتكوين التوازن لكل مجموعة في **لوحة المعلومات → المجموعات → إنشاء/تحرير → الإستراتيجية**.
|
||||
Configure per-combo balancing in **Dashboard → Combos → Create/Edit → Strategy**.
|
||||
|
||||
| استراتيجية | الوصف |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| **جولة روبن** | يدور عبر النماذج بالتتابع |
|
||||
| **الأولوية** | يحاول دائمًا النموذج الأول؛ لا يعود إلا على الخطأ |
|
||||
| **عشوائي** | يختار نموذجًا عشوائيًا من المجموعة لكل طلب |
|
||||
| **المرجح** | تعتمد المسارات بشكل متناسب على الأوزان المخصصة لكل نموذج |
|
||||
| **الأقل استخدامًا** | التوجيهات إلى النموذج الذي يحتوي على أقل عدد من الطلبات الأخيرة (يستخدم مقاييس التحرير والسرد) |
|
||||
| **التكلفة الأمثل** | الطرق إلى أرخص طراز متاح (يستخدم جدول التسعير) |
|
||||
| Strategy | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------ |
|
||||
| **Round-Robin** | Rotates through models sequentially |
|
||||
| **Priority** | Always tries the first model; falls back only on error |
|
||||
| **Random** | Picks a random model from the combo for each request |
|
||||
| **Weighted** | Routes proportionally based on assigned weights per model |
|
||||
| **Least-Used** | Routes to the model with the fewest recent requests (uses combo metrics) |
|
||||
| **Cost-Optimized** | Routes to the cheapest available model (uses pricing table) |
|
||||
|
||||
يمكن ضبط إعدادات التحرير والسرد العامة في **لوحة المعلومات → الإعدادات → التوجيه → إعدادات التحرير والسرد الافتراضية**.
|
||||
Global combo defaults can be set in **Dashboard → Settings → Routing → Combo Defaults**.
|
||||
|
||||
---
|
||||
|
||||
### لوحة المعلومات الصحية
|
||||
### Health Dashboard
|
||||
|
||||
الوصول عبر **لوحة التحكم → الصحة**. نظرة عامة على صحة النظام في الوقت الحقيقي مع 6 بطاقات:
|
||||
Access via **Dashboard → Health**. Real-time system health overview with 6 cards:
|
||||
|
||||
| بطاقة | ما يظهر |
|
||||
| ---------------------------------- | -------------------------------------------------------------- |
|
||||
| **حالة النظام** | وقت التشغيل، الإصدار، استخدام الذاكرة، دليل البيانات |
|
||||
| ** صحة المزود ** | حالة قاطع الدائرة الكهربائية لكل مزود (مغلق/مفتوح/نصف مفتوح) |
|
||||
| ** حدود المعدل ** | فترات تهدئة حد المعدل النشط لكل حساب مع الوقت المتبقي |
|
||||
| ** عمليات التأمين النشطة ** | تم حظر مقدمي الخدمة مؤقتًا بواسطة سياسة التأمين |
|
||||
| ** ذاكرة التخزين المؤقت للتوقيع ** | إحصائيات إلغاء البيانات المكررة (المفاتيح النشطة، معدل الدخول) |
|
||||
| ** قياس زمن الوصول ** | p50/p95/p99 تجميع زمن الوصول لكل مزود |
|
||||
| Card | What It Shows |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| **System Status** | Uptime, version, memory usage, data directory |
|
||||
| **Provider Health** | Per-provider circuit breaker state (Closed/Open/Half-Open) |
|
||||
| **Rate Limits** | Active rate limit cooldowns per account with remaining time |
|
||||
| **Active Lockouts** | Providers temporarily blocked by the lockout policy |
|
||||
| **Signature Cache** | Deduplication cache stats (active keys, hit rate) |
|
||||
| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider |
|
||||
|
||||
**نصيحة احترافية:** يتم تحديث صفحة الصحة تلقائيًا كل 10 ثوانٍ. استخدم بطاقة قاطع الدائرة لتحديد مقدمي الخدمة الذين يواجهون مشكلات.
|
||||
**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop Application (Electron)
|
||||
|
||||
OmniRoute is available as a native desktop application for Windows, macOS, and Linux.
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# From the electron directory:
|
||||
cd electron
|
||||
npm install
|
||||
|
||||
# Development mode (connect to running Next.js dev server):
|
||||
npm run dev
|
||||
|
||||
# Production mode (uses standalone build):
|
||||
npm start
|
||||
```
|
||||
|
||||
### Building Installers
|
||||
|
||||
```bash
|
||||
cd electron
|
||||
npm run build # Current platform
|
||||
npm run build:win # Windows (.exe NSIS)
|
||||
npm run build:mac # macOS (.dmg universal)
|
||||
npm run build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
Output → `electron/dist-electron/`
|
||||
|
||||
### Key Features
|
||||
|
||||
| Feature | Description |
|
||||
| --------------------------- | ---------------------------------------------------- |
|
||||
| **Server Readiness** | Polls server before showing window (no blank screen) |
|
||||
| **System Tray** | Minimize to tray, change port, quit from tray menu |
|
||||
| **Port Management** | Change server port from tray (auto-restarts server) |
|
||||
| **Content Security Policy** | Restrictive CSP via session headers |
|
||||
| **Single Instance** | Only one app instance can run at a time |
|
||||
| **Offline Mode** | Bundled Next.js server works without internet |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------- | -------------------------------- |
|
||||
| `OMNIROUTE_PORT` | `20128` | Server port |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (64–16384 MB) |
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](../electron/README.md)
|
||||
|
||||
401
docs/i18n/ar/VM_DEPLOYMENT_GUIDE.md
Normal file
401
docs/i18n/ar/VM_DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,401 @@
|
||||
# OmniRoute — دليل النشر على VM باستخدام Cloudflare
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](../es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](../fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](../it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](../ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](../de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](../in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](../th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](../ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](../ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](../bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](../da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](../fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](../he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](../hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](../ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](../nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](../no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](../ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](../pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](../sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](../phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](../cs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
الدليل الكامل لتثبيت OmniRoute وتكوينه على VM (VPS) مع المجال المُدار عبر Cloudflare.
|
||||
|
||||
---
|
||||
|
||||
## المتطلبات الأساسية
|
||||
|
||||
| العنصر | الحد الأدنى | موصى به |
|
||||
| ---------------------------- | ----------------------------------- | ----------------------------------- |
|
||||
| ** وحدة المعالجة المركزية ** | 1 وحدة المعالجة المركزية الافتراضية | 2 وحدة المعالجة المركزية الافتراضية |
|
||||
| **ذاكرة الوصول العشوائي** | 1 جيجا | 2 جيجا |
|
||||
| **القرص** | 10 جيجا اس اس دي | 25 جيجا اس اس دي |
|
||||
| **نظام التشغيل** | أوبونتو 22.04 LTS | أوبونتو 24.04 LTS |
|
||||
| **المجال** | مسجل في Cloudflare | — |
|
||||
| ** عامل الميناء ** | محرك دوكر 24+ | عامل الميناء 27+ |
|
||||
|
||||
**المزودون الذين تم اختبارهم**: Akamai (Linode)، DigitalOcean، Vultr، Hetzner، AWS Lightsail.
|
||||
|
||||
---
|
||||
|
||||
## 1. قم بتكوين الجهاز الافتراضي
|
||||
|
||||
### 1.1 إنشاء المثيل
|
||||
|
||||
على موفر VPS المفضل لديك:
|
||||
|
||||
- اختر Ubuntu 24.04 LTS
|
||||
- حدد الحد الأدنى للخطة (1 vCPU / 1 جيجابايت من ذاكرة الوصول العشوائي)
|
||||
- قم بتعيين كلمة مرور جذر قوية أو قم بتكوين مفتاح SSH
|
||||
- لاحظ **عنوان IP العام** (على سبيل المثال، `203.0.113.10`)
|
||||
|
||||
### 1.2 الاتصال عبر SSH
|
||||
|
||||
```bash
|
||||
ssh root@203.0.113.10
|
||||
```
|
||||
|
||||
### 1.3 تحديث النظام
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
|
||||
### 1.4 تثبيت عامل الميناء
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
apt install -y ca-certificates curl gnupg
|
||||
|
||||
# Add official Docker repository
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $ (. /etc/os-release && echo “$VERSION_CODENAME”) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt update
|
||||
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
|
||||
### 1.5 تثبيت nginx
|
||||
|
||||
```bash
|
||||
apt install -y nginx
|
||||
```
|
||||
|
||||
### 1.6 تكوين جدار الحماية (UFW)
|
||||
|
||||
```bash
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow 22/tcp # SSH
|
||||
ufw allow 80/tcp # HTTP (redirect)
|
||||
ufw allow 443/tcp # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
> **نصيحة**: للحصول على الحد الأقصى من الأمان، قم بتقييد المنفذين 80 و443 بعناوين Cloudflare IP فقط. راجع قسم [Advanced Security](#advanced-security).
|
||||
|
||||
---
|
||||
|
||||
## 2. قم بتثبيت OmniRoute
|
||||
|
||||
### 2.1 إنشاء دليل التكوين
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/omniroute
|
||||
```
|
||||
|
||||
### 2.2 إنشاء ملف متغيرات البيئة
|
||||
|
||||
```bash
|
||||
cat > /opt/omniroute/.env << ‘EOF’
|
||||
# === Security ===
|
||||
JWT_SECRET=CHANGE-TO-A-UNIQUE-64-CHAR-SECRET-KEY
|
||||
INITIAL_PASSWORD=YourSecurePassword123!
|
||||
API_KEY_SECRET=REPLACE-WITH-ANOTHER-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY=REPLACE-WITH-THIRD-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY_VERSION=v1
|
||||
MACHINE_ID_SALT=CHANGE-TO-A-UNIQUE-SALT
|
||||
|
||||
# === App ===
|
||||
PORT=20128
|
||||
NODE_ENV=production
|
||||
HOSTNAME=0.0.0.0
|
||||
DATA_DIR=/app/data
|
||||
STORAGE_DRIVER=sqlite
|
||||
ENABLE_REQUEST_LOGS=true
|
||||
AUTH_COOKIE_SECURE=false
|
||||
REQUIRE_API_KEY=false
|
||||
|
||||
# === Domain (change to your domain) ===
|
||||
BASE_URL=https://llms.seudominio.com
|
||||
NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
|
||||
|
||||
# === Cloud Sync (optional) ===
|
||||
# CLOUD_URL=https://cloud.omniroute.online
|
||||
# NEXT_PUBLIC_CLOUD_URL=https://cloud.omniroute.online
|
||||
EOF
|
||||
```
|
||||
|
||||
> ⚠️ **هام**: أنشئ مفاتيح سرية فريدة! استخدم `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
|
||||
```
|
||||
|
||||
### 2.4 التحقق من أنه قيد التشغيل
|
||||
|
||||
```bash
|
||||
docker ps | grep omniroute
|
||||
docker logs omniroute --tail 20
|
||||
```
|
||||
|
||||
يجب أن يعرض: `[DB] SQLite database ready` و`listening on port 20128`.
|
||||
|
||||
---
|
||||
|
||||
## 3. تكوين nginx (الوكيل العكسي)
|
||||
|
||||
### 3.1 إنشاء شهادة SSL (أصل Cloudflare)
|
||||
|
||||
في لوحة معلومات Cloudflare:
|
||||
|
||||
1. انتقل إلى **SSL/TLS → خادم الأصل**
|
||||
2. انقر **إنشاء شهادة**
|
||||
3. احتفظ بالإعدادات الافتراضية (15 عامًا، \*.yourdomain.com)
|
||||
4. انسخ **شهادة المنشأ** و**المفتاح الخاص**
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### 3.2 تكوين إنجينكس
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
|
||||
# Default server — blocks direct access via IP
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
server_name _;
|
||||
return 444;
|
||||
}
|
||||
|
||||
# OmniRoute — HTTPS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name llms.yourdomain.com; # Change to your domain
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_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 X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection “upgrade”;
|
||||
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTP → HTTPS redirect
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name llms.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
NGINX
|
||||
```
|
||||
|
||||
### 3.3 تمكين واختبار
|
||||
|
||||
```bash
|
||||
# Remove default configuration
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Enable OmniRoute
|
||||
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
|
||||
|
||||
# Test and reload
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. تكوين Cloudflare DNS
|
||||
|
||||
### 4.1 إضافة سجل DNS
|
||||
|
||||
في لوحة معلومات Cloudflare → DNS:
|
||||
|
||||
| اكتب | الاسم | المحتوى | الوكيل |
|
||||
| ---- | ------ | ---------------------- | -------- |
|
||||
| أ | `llms` | `203.0.113.10` (VM IP) | ✅ توكيل |
|
||||
|
||||
### 4.2 تكوين SSL
|
||||
|
||||
ضمن **SSL/TLS → نظرة عامة**:
|
||||
|
||||
- الوضع: **كامل (صارم)**
|
||||
|
||||
ضمن **SSL/TLS → شهادات الحافة**:
|
||||
|
||||
- استخدم HTTPS دائمًا: ✅ قيد التشغيل
|
||||
- الحد الأدنى لإصدار TLS: TLS 1.2
|
||||
- إعادة كتابة HTTPS تلقائيًا: ✅ تشغيل
|
||||
|
||||
### 4.3 الاختبار
|
||||
|
||||
```bash
|
||||
curl -sI https://llms.seudominio.com/health
|
||||
# Should return HTTP/2 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. العمليات والصيانة
|
||||
|
||||
### الترقية إلى الإصدار الجديد
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### عرض السجلات
|
||||
|
||||
```bash
|
||||
docker logs -f omniroute # Real-time stream
|
||||
docker logs omniroute --tail 50 # Last 50 lines
|
||||
```
|
||||
|
||||
### النسخ الاحتياطي لقاعدة البيانات يدويا
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### الاستعادة من النسخة الاحتياطية
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. الأمان المتقدم
|
||||
|
||||
### تقييد nginx على عناوين IP الخاصة بـ Cloudflare
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
|
||||
# Cloudflare IPv4 ranges — update periodically
|
||||
# https://www.cloudflare.com/ips-v4/
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
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_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
|
||||
```
|
||||
|
||||
أضف ما يلي إلى `nginx.conf` داخل الكتلة `http {}`:
|
||||
|
||||
```nginx
|
||||
include /etc/nginx/cloudflare-ips.conf;
|
||||
```
|
||||
|
||||
### تثبيت Fail2ban
|
||||
|
||||
```bash
|
||||
apt install -y fail2ban
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
# Check status
|
||||
fail2ban-client status sshd
|
||||
```
|
||||
|
||||
### منع الوصول المباشر إلى منفذ Docker
|
||||
|
||||
```bash
|
||||
# Prevent direct external access to port 20128
|
||||
iptables -I DOCKER-USER -p tcp --dport 20128 -j DROP
|
||||
iptables -I DOCKER-USER -i lo -p tcp --dport 20128 -j ACCEPT
|
||||
|
||||
# Persist the rules
|
||||
apt install -y iptables-persistent
|
||||
netfilter-persistent save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. النشر إلى عمال Cloudflare (اختياري)
|
||||
|
||||
للوصول عن بعد عبر Cloudflare Workers (دون الكشف عن الجهاز الافتراضي مباشرة):
|
||||
|
||||
```bash
|
||||
# In the local repository
|
||||
cd omnirouteCloud
|
||||
npm install
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
راجع الوثائق الكاملة على [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
|
||||
---
|
||||
|
||||
## ملخص المنفذ
|
||||
|
||||
| ميناء | الخدمة | الوصول |
|
||||
| ----- | ------------- | ----------------------------- |
|
||||
| 22 | سش | عام (مع Fail2ban) |
|
||||
| 80 | إنجينكس HTTP | إعادة التوجيه → HTTPS |
|
||||
| 443 | إنجينكس HTTPS | عبر وكيل Cloudflare |
|
||||
| 20128 | أومنيروتي | المضيف المحلي فقط (عبر nginx) |
|
||||
200
docs/i18n/bg/A2A-SERVER.md
Normal file
200
docs/i18n/bg/A2A-SERVER.md
Normal file
@@ -0,0 +1,200 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/A2A-SERVER.md) · 🇪🇸 [es](../es/A2A-SERVER.md) · 🇫🇷 [fr](../fr/A2A-SERVER.md) · 🇩🇪 [de](../de/A2A-SERVER.md) · 🇮🇹 [it](../it/A2A-SERVER.md) · 🇷🇺 [ru](../ru/A2A-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/A2A-SERVER.md) · 🇯🇵 [ja](../ja/A2A-SERVER.md) · 🇰🇷 [ko](../ko/A2A-SERVER.md) · 🇸🇦 [ar](../ar/A2A-SERVER.md) · 🇮🇳 [in](../in/A2A-SERVER.md) · 🇹🇭 [th](../th/A2A-SERVER.md) · 🇻🇳 [vi](../vi/A2A-SERVER.md) · 🇮🇩 [id](../id/A2A-SERVER.md) · 🇲🇾 [ms](../ms/A2A-SERVER.md) · 🇳🇱 [nl](../nl/A2A-SERVER.md) · 🇵🇱 [pl](../pl/A2A-SERVER.md) · 🇸🇪 [sv](../sv/A2A-SERVER.md) · 🇳🇴 [no](../no/A2A-SERVER.md) · 🇩🇰 [da](../da/A2A-SERVER.md) · 🇫🇮 [fi](../fi/A2A-SERVER.md) · 🇵🇹 [pt](../pt/A2A-SERVER.md) · 🇷🇴 [ro](../ro/A2A-SERVER.md) · 🇭🇺 [hu](../hu/A2A-SERVER.md) · 🇧🇬 [bg](../bg/A2A-SERVER.md) · 🇸🇰 [sk](../sk/A2A-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/A2A-SERVER.md) · 🇮🇱 [he](../he/A2A-SERVER.md) · 🇵🇭 [phi](../phi/A2A-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute A2A Server Documentation
|
||||
|
||||
> Agent-to-Agent Protocol v0.3 — OmniRoute as an intelligent routing agent
|
||||
|
||||
## Agent Discovery
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
Returns the Agent Card describing OmniRoute's capabilities, skills, and authentication requirements.
|
||||
|
||||
---
|
||||
|
||||
## Authentication
|
||||
|
||||
All `/a2a` requests require an API key via the `Authorization` header:
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
If no API key is configured on the server, authentication is bypassed.
|
||||
|
||||
---
|
||||
|
||||
## JSON-RPC 2.0 Methods
|
||||
|
||||
### `message/send` — Synchronous Execution
|
||||
|
||||
Sends a message to a skill and waits for the complete response.
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/a2a \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Authorization: Bearer YOUR_KEY" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/send",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Write a hello world in Python"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**Response:**
|
||||
|
||||
```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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `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 '{
|
||||
"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":"..."}}}
|
||||
|
||||
: heartbeat 2026-03-03T17:00:00Z
|
||||
|
||||
data: {"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"}}'
|
||||
```
|
||||
|
||||
### `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"}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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. |
|
||||
|
||||
---
|
||||
|
||||
## Task Lifecycle
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
|
||||
- Tasks expire after 5 minutes (configurable)
|
||||
- Terminal states: `completed`, `failed`, `cancelled`
|
||||
- Event log tracks every state transition
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
---
|
||||
|
||||
## Integration Examples
|
||||
|
||||
### Python (requests)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
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"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
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",
|
||||
},
|
||||
body: 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);
|
||||
```
|
||||
@@ -1,12 +1,16 @@
|
||||
# Справка за API
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](../es/API_REFERENCE.md) | 🇫🇷 [Français](../fr/API_REFERENCE.md) | 🇮🇹 [Italiano](../it/API_REFERENCE.md) | 🇷🇺 [Русский](../ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](../zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](../de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](../in/API_REFERENCE.md) | 🇹🇭 [ไทย](../th/API_REFERENCE.md) | 🇺🇦 [Українська](../uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](../ar/API_REFERENCE.md) | 🇯🇵 [日本語](../ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](../vi/API_REFERENCE.md) | 🇧🇬 [Български](../bg/API_REFERENCE.md) | 🇩🇰 [Dansk](../da/API_REFERENCE.md) | 🇫🇮 [Suomi](../fi/API_REFERENCE.md) | 🇮🇱 [עברית](../he/API_REFERENCE.md) | 🇭🇺 [Magyar](../hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](../id/API_REFERENCE.md) | 🇰🇷 [한국어](../ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](../ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](../nl/API_REFERENCE.md) | 🇳🇴 [Norsk](../no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](../pt/API_REFERENCE.md) | 🇷🇴 [Română](../ro/API_REFERENCE.md) | 🇵🇱 [Polski](../pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](../sk/API_REFERENCE.md) | 🇸🇪 [Svenska](../sv/API_REFERENCE.md) | 🇵🇭 [Filipino](../phi/API_REFERENCE.md)
|
||||
|
||||
Пълна справка за всички крайни точки на OmniRoute API.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/API_REFERENCE.md) · 🇪🇸 [es](../es/API_REFERENCE.md) · 🇫🇷 [fr](../fr/API_REFERENCE.md) · 🇩🇪 [de](../de/API_REFERENCE.md) · 🇮🇹 [it](../it/API_REFERENCE.md) · 🇷🇺 [ru](../ru/API_REFERENCE.md) · 🇨🇳 [zh-CN](../zh-CN/API_REFERENCE.md) · 🇯🇵 [ja](../ja/API_REFERENCE.md) · 🇰🇷 [ko](../ko/API_REFERENCE.md) · 🇸🇦 [ar](../ar/API_REFERENCE.md) · 🇮🇳 [in](../in/API_REFERENCE.md) · 🇹🇭 [th](../th/API_REFERENCE.md) · 🇻🇳 [vi](../vi/API_REFERENCE.md) · 🇮🇩 [id](../id/API_REFERENCE.md) · 🇲🇾 [ms](../ms/API_REFERENCE.md) · 🇳🇱 [nl](../nl/API_REFERENCE.md) · 🇵🇱 [pl](../pl/API_REFERENCE.md) · 🇸🇪 [sv](../sv/API_REFERENCE.md) · 🇳🇴 [no](../no/API_REFERENCE.md) · 🇩🇰 [da](../da/API_REFERENCE.md) · 🇫🇮 [fi](../fi/API_REFERENCE.md) · 🇵🇹 [pt](../pt/API_REFERENCE.md) · 🇷🇴 [ro](../ro/API_REFERENCE.md) · 🇭🇺 [hu](../hu/API_REFERENCE.md) · 🇧🇬 [bg](../bg/API_REFERENCE.md) · 🇸🇰 [sk](../sk/API_REFERENCE.md) · 🇺🇦 [uk-UA](../uk-UA/API_REFERENCE.md) · 🇮🇱 [he](../he/API_REFERENCE.md) · 🇵🇭 [phi](../phi/API_REFERENCE.md)
|
||||
|
||||
---
|
||||
|
||||
## Съдържание
|
||||
# API Reference
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](API_REFERENCE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵 [日本語](i18n/ja/API_REFERENCE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dansk](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [Magyar](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nederlands](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipino](i18n/phi/API_REFERENCE.md)
|
||||
|
||||
Complete reference for all OmniRoute API endpoints.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Chat Completions](#chat-completions)
|
||||
- [Embeddings](#embeddings)
|
||||
@@ -20,7 +24,7 @@
|
||||
|
||||
---
|
||||
|
||||
## Завършвания на чат
|
||||
## Chat Completions
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
@@ -36,21 +40,21 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
### Персонализирани заглавки
|
||||
### Custom Headers
|
||||
|
||||
| Заглавка | Посока | Описание |
|
||||
| ------------------------ | ------- | ------------------------------------------ |
|
||||
| `X-OmniRoute-No-Cache` | Заявка | Задайте `true` за заобикаляне на кеша |
|
||||
| `X-OmniRoute-Progress` | Заявка | Задайте `true` за събития за прогрес |
|
||||
| `Idempotency-Key` | Заявка | Ключ за дедупиране (5s прозорец) |
|
||||
| `X-Request-Id` | Заявка | Алтернативен дедуп ключ |
|
||||
| `X-OmniRoute-Cache` | Отговор | `HIT` или `MISS` (без поточно предаване) |
|
||||
| `X-OmniRoute-Idempotent` | Отговор | `true` ако е дедупликиран |
|
||||
| `X-OmniRoute-Progress` | Отговор | `enabled` ако проследяване на напредъка на |
|
||||
| Header | Direction | Description |
|
||||
| ------------------------ | --------- | --------------------------------- |
|
||||
| `X-OmniRoute-No-Cache` | Request | Set to `true` to bypass cache |
|
||||
| `X-OmniRoute-Progress` | Request | Set to `true` for progress events |
|
||||
| `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 |
|
||||
|
||||
---
|
||||
|
||||
## Вграждания
|
||||
## Embeddings
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
@@ -63,7 +67,7 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
Налични доставчици: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
Available providers: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
@@ -72,7 +76,7 @@ GET /v1/embeddings
|
||||
|
||||
---
|
||||
|
||||
## Генериране на изображения
|
||||
## Image Generation
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
@@ -86,7 +90,7 @@ Content-Type: application/json
|
||||
}
|
||||
```
|
||||
|
||||
Налични доставчици: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
Available providers: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
@@ -95,7 +99,7 @@ GET /v1/images/generations
|
||||
|
||||
---
|
||||
|
||||
## Списък с модели
|
||||
## List Models
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
@@ -106,22 +110,22 @@ Authorization: Bearer your-api-key
|
||||
|
||||
---
|
||||
|
||||
## Крайни точки за съвместимост
|
||||
## Compatibility Endpoints
|
||||
|
||||
| Метод | Път | Формат |
|
||||
| ---------- | --------------------------- | -------------------------- |
|
||||
| ПУБЛИКАЦИЯ | `/v1/chat/completions` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/messages` | Антропен |
|
||||
| ПУБЛИКАЦИЯ | `/v1/responses` | OpenAI отговори |
|
||||
| ПУБЛИКАЦИЯ | `/v1/embeddings` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/images/generations` | OpenAI |
|
||||
| ВЗЕМЕТЕ | `/v1/models` | OpenAI |
|
||||
| ПУБЛИКАЦИЯ | `/v1/messages/count_tokens` | Антропен |
|
||||
| ВЗЕМЕТЕ | `/v1beta/models` | Близнаци |
|
||||
| ПУБЛИКАЦИЯ | `/v1beta/models/{...path}` | Gemini генерира съдържание |
|
||||
| ПУБЛИКАЦИЯ | `/v1/api/chat` | Олама |
|
||||
| Method | Path | Format |
|
||||
| ------ | --------------------------- | ---------------------- |
|
||||
| POST | `/v1/chat/completions` | OpenAI |
|
||||
| POST | `/v1/messages` | Anthropic |
|
||||
| POST | `/v1/responses` | OpenAI Responses |
|
||||
| POST | `/v1/embeddings` | OpenAI |
|
||||
| POST | `/v1/images/generations` | OpenAI |
|
||||
| GET | `/v1/models` | OpenAI |
|
||||
| POST | `/v1/messages/count_tokens` | Anthropic |
|
||||
| GET | `/v1beta/models` | Gemini |
|
||||
| POST | `/v1beta/models/{...path}` | Gemini generateContent |
|
||||
| POST | `/v1/api/chat` | Ollama |
|
||||
|
||||
### Специализирани маршрути на доставчик
|
||||
### Dedicated Provider Routes
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
@@ -129,11 +133,11 @@ POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
Префиксът на доставчика се добавя автоматично, ако липсва. Несъответстващите модели връщат `400`.
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
---
|
||||
|
||||
## Семантичен кеш
|
||||
## Semantic Cache
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
@@ -143,7 +147,7 @@ GET /api/cache
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
Пример за отговор:
|
||||
Response example:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -162,154 +166,164 @@ DELETE /api/cache
|
||||
|
||||
---
|
||||
|
||||
## Табло за управление и управление
|
||||
## Dashboard & Management
|
||||
|
||||
### Удостоверяване
|
||||
### Authentication
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------------- | ------------- | ---------------------------------- |
|
||||
| `/api/auth/login` | ПУБЛИКАЦИЯ | Вход |
|
||||
| `/api/auth/logout` | ПУБЛИКАЦИЯ | Изход |
|
||||
| `/api/settings/require-login` | ВЗЕМИ/ПОСТАВИ | Изисква се превключване на влизане |
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------------- | ------- | --------------------- |
|
||||
| `/api/auth/login` | POST | Login |
|
||||
| `/api/auth/logout` | POST | Logout |
|
||||
| `/api/settings/require-login` | GET/PUT | Toggle login required |
|
||||
|
||||
### Управление на доставчика
|
||||
### Provider Management
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------- | -------------------------------- | ---------------------------------------- |
|
||||
| `/api/providers` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Списък / създаване на доставчици |
|
||||
| `/api/providers/[id]` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Управление на доставчик |
|
||||
| `/api/providers/[id]/test` | ПУБЛИКАЦИЯ | Тествайте връзката с доставчик |
|
||||
| `/api/providers/[id]/models` | ВЗЕМЕТЕ | Избройте модели на доставчици |
|
||||
| `/api/providers/validate` | ПУБЛИКАЦИЯ | Проверка на конфигурацията на доставчика |
|
||||
| `/api/provider-nodes*` | Различни | Управление на възел на доставчик |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Персонализирани модели |
|
||||
| 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 |
|
||||
|
||||
### OAuth потоци
|
||||
### OAuth Flows
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------------- | -------- | ------------------------------ |
|
||||
| `/api/oauth/[provider]/[action]` | Различни | Специфичен за доставчика OAuth |
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------------- | ------- | ----------------------- |
|
||||
| `/api/oauth/[provider]/[action]` | Various | Provider-specific OAuth |
|
||||
|
||||
### Маршрутизиране и конфигурация
|
||||
### Routing & Config
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------- | -------------------- | -------------------------------- |
|
||||
| `/api/models/alias` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Псевдоними на модели |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Всички модели по доставчик + тип |
|
||||
| `/api/combos*` | Различни | Комбо управление |
|
||||
| `/api/keys*` | Различни | Управление на API ключове |
|
||||
| `/api/pricing` | ВЗЕМЕТЕ | Моделна цена |
|
||||
| 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 |
|
||||
|
||||
### Използване и анализ
|
||||
### Usage & Analytics
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ------- | ----------------------- |
|
||||
| `/api/usage/history` | ВЗЕМЕТЕ | История на използването |
|
||||
| `/api/usage/logs` | ВЗЕМЕТЕ | Дневници за използване |
|
||||
| `/api/usage/request-logs` | ВЗЕМЕТЕ | Дневници на ниво заявка |
|
||||
| `/api/usage/[connectionId]` | ВЗЕМЕТЕ | Използване на връзка |
|
||||
| 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 |
|
||||
|
||||
### Настройки
|
||||
### Settings
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------------- | ------------- | -------------------------------------- |
|
||||
| `/api/settings` | ВЗЕМИ/ПОСТАВИ | Общи настройки |
|
||||
| `/api/settings/proxy` | ВЗЕМИ/ПОСТАВИ | Конфигурация на мрежов прокси |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Тествайте прокси връзката |
|
||||
| `/api/settings/ip-filter` | ВЗЕМИ/ПОСТАВИ | Списък с разрешени/блокирани IP адреси |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Бюджет на жетон за разсъждение |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Глобална системна подкана |
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------------- | ------- | ---------------------- |
|
||||
| `/api/settings` | GET/PUT | 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 |
|
||||
|
||||
### Мониторинг
|
||||
### Monitoring
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------------------ | -------------------- | ----------------------------- |
|
||||
| `/api/sessions` | ВЗЕМЕТЕ | Проследяване на активна сесия |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Лимити за лихви по сметка |
|
||||
| `/api/monitoring/health` | ВЗЕМЕТЕ | Здравна проверка |
|
||||
| `/api/cache` | ПОЛУЧАВАНЕ/ИЗТРИВАНЕ | Кеш статистики / изчистване |
|
||||
| Endpoint | Method | Description |
|
||||
| ------------------------ | ---------- | ----------------------- |
|
||||
| `/api/sessions` | GET | Active session tracking |
|
||||
| `/api/rate-limits` | GET | Per-account rate limits |
|
||||
| `/api/monitoring/health` | GET | Health check |
|
||||
| `/api/cache` | GET/DELETE | Cache stats / clear |
|
||||
|
||||
### Архивиране и експортиране/импортиране
|
||||
### Backup & Export/Import
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ---------- | ------------------------------------------------ |
|
||||
| `/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 архив |
|
||||
| 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
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------- | ---------- | ---------------------------------- |
|
||||
| `/api/sync/cloud` | Различни | Операции за синхронизиране в облак |
|
||||
| `/api/sync/initialize` | ПУБЛИКАЦИЯ | Инициализиране на синхронизиране |
|
||||
| `/api/cloud/*` | Различни | Облачно управление |
|
||||
| Endpoint | Method | Description |
|
||||
| ---------------------- | ------- | --------------------- |
|
||||
| `/api/sync/cloud` | Various | Cloud sync operations |
|
||||
| `/api/sync/initialize` | POST | Initialize sync |
|
||||
| `/api/cloud/*` | Various | Cloud management |
|
||||
|
||||
### CLI инструменти
|
||||
### CLI Tools
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ---------------------------------- | ------- | ---------------------- |
|
||||
| `/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 |
|
||||
| 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 |
|
||||
|
||||
CLI отговорите включват: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
CLI responses include: `installed`, `runnable`, `command`, `commandPath`, `runtimeMode`, `reason`.
|
||||
|
||||
### Устойчивост и ограничения на скоростта
|
||||
### ACP Agents
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ----------------------- | ------------- | --------------------------------------------- |
|
||||
| `/api/resilience` | ВЗЕМИ/ПОСТАВИ | Вземете/актуализирайте профили за устойчивост |
|
||||
| `/api/resilience/reset` | ПУБЛИКАЦИЯ | Нулиране на прекъсвачи |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка |
|
||||
| `/api/rate-limit` | ВЗЕМЕТЕ | Конфигурация на глобален лимит на скоростта |
|
||||
| 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).
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| ------------ | -------------------- | --------------------------------------- |
|
||||
| `/api/evals` | ВЗЕМЕТЕ/ПУБЛИКУВАЙТЕ | Избройте eval пакети / изпълнете оценка |
|
||||
### Resilience & Rate Limits
|
||||
|
||||
### Политики
|
||||
| Endpoint | Method | Description |
|
||||
| ----------------------- | ------- | ------------------------------- |
|
||||
| `/api/resilience` | GET/PUT | 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/policies` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | Управление на правилата за маршрутизиране |
|
||||
### Evals
|
||||
|
||||
### Съответствие
|
||||
| Endpoint | Method | Description |
|
||||
| ------------ | -------- | --------------------------------- |
|
||||
| `/api/evals` | GET/POST | List eval suites / run evaluation |
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------------------- | ------- | -------------------------------------------------- |
|
||||
| `/api/compliance/audit-log` | ВЗЕМЕТЕ | Дневник за проверка на съответствието (последно N) |
|
||||
### Policies
|
||||
|
||||
### v1beta (съвместим с Gemini)
|
||||
| Endpoint | Method | Description |
|
||||
| --------------- | --------------- | ----------------------- |
|
||||
| `/api/policies` | GET/POST/DELETE | Manage routing policies |
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| -------------------------- | ---------- | ------------------------------------- |
|
||||
| `/v1beta/models` | ВЗЕМЕТЕ | Избройте модели във формат Gemini |
|
||||
| `/v1beta/models/{...path}` | ПУБЛИКАЦИЯ | Gemini `generateContent` крайна точка |
|
||||
### Compliance
|
||||
|
||||
Тези крайни точки отразяват API формата на Gemini за клиенти, които очакват естествена съвместимост с Gemini SDK.
|
||||
| Endpoint | Method | Description |
|
||||
| --------------------------- | ------ | ----------------------------- |
|
||||
| `/api/compliance/audit-log` | GET | Compliance audit log (last N) |
|
||||
|
||||
### Вътрешен/системен API
|
||||
### v1beta (Gemini-Compatible)
|
||||
|
||||
| Крайна точка | Метод | Описание |
|
||||
| --------------- | ---------- | ------------------------------------------------------------------------------ |
|
||||
| `/api/init` | ВЗЕМЕТЕ | Проверка за инициализация на приложението (използва се при първото стартиране) |
|
||||
| `/api/tags` | ВЗЕМЕТЕ | Тагове за модели, съвместими с Ollama (за клиенти на Ollama) |
|
||||
| `/api/restart` | ПУБЛИКАЦИЯ | Задейства грациозно рестартиране на сървъра |
|
||||
| `/api/shutdown` | ПУБЛИКАЦИЯ | Задействайте грациозно изключване на сървъра |
|
||||
| Endpoint | Method | Description |
|
||||
| -------------------------- | ------ | --------------------------------- |
|
||||
| `/v1beta/models` | GET | List models in Gemini format |
|
||||
| `/v1beta/models/{...path}` | POST | Gemini `generateContent` endpoint |
|
||||
|
||||
> **Забележка:** Тези крайни точки се използват вътрешно от системата или за съвместимост с клиента Ollama. Те обикновено не се извикват от крайните потребители.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Аудио транскрипция
|
||||
## Audio Transcription
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
@@ -317,9 +331,9 @@ Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
Транскрибирайте аудио файлове с помощта на Deepgram или AssemblyAI.
|
||||
Transcribe audio files using Deepgram or AssemblyAI.
|
||||
|
||||
**Заявка:**
|
||||
**Request:**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
@@ -328,7 +342,7 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
**Отговор:**
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -339,15 +353,15 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
}
|
||||
```
|
||||
|
||||
**Поддържани доставчици:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
**Supported providers:** `deepgram/nova-3`, `assemblyai/best`.
|
||||
|
||||
**Поддържани формати:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
**Supported formats:** `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
## Съвместимост с Ollama
|
||||
## Ollama Compatibility
|
||||
|
||||
За клиенти, които използват API формат на Ollama:
|
||||
For clients that use Ollama's API format:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
@@ -357,18 +371,18 @@ POST /v1/api/chat
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Заявките се превеждат автоматично между Ollama и вътрешни формати.
|
||||
Requests are automatically translated between Ollama and internal formats.
|
||||
|
||||
---
|
||||
|
||||
## Телеметрия
|
||||
## Telemetry
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**Отговор:**
|
||||
**Response:**
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -381,7 +395,7 @@ GET /api/telemetry/summary
|
||||
|
||||
---
|
||||
|
||||
## Бюджет
|
||||
## Budget
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
@@ -400,7 +414,7 @@ Content-Type: application/json
|
||||
|
||||
---
|
||||
|
||||
## Наличност на модела
|
||||
## Model Availability
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
@@ -417,25 +431,25 @@ Content-Type: application/json
|
||||
|
||||
---
|
||||
|
||||
## Обработка на заявка
|
||||
## Request Processing
|
||||
|
||||
1. Клиентът изпраща заявка до `/v1/*`
|
||||
2. Обработчикът на маршрута извиква `handleChat`, `handleEmbedding`, `handleAudioTranscription` или `handleImageGeneration`
|
||||
3. Моделът е разрешен (директен доставчик/модел или псевдоним/комбо)
|
||||
4. Идентификационни данни, избрани от локална база данни с филтриране на наличността на акаунта
|
||||
5. За чат: `handleChatCore` — откриване на формат, превод, проверка на кеша, проверка на идемпотентност
|
||||
6. Изпълнителят на доставчика изпраща заявка нагоре по веригата
|
||||
7. Отговор, преведен обратно във формат на клиента (чат) или върнат такъв, какъвто е (вграждания/изображения/аудио)
|
||||
8. Записано използване/регистриране
|
||||
9. Резервният вариант се прилага при грешки според комбо правилата
|
||||
1. Client sends request to `/v1/*`
|
||||
2. Route handler calls `handleChat`, `handleEmbedding`, `handleAudioTranscription`, or `handleImageGeneration`
|
||||
3. Model is resolved (direct provider/model or alias/combo)
|
||||
4. Credentials selected from local DB with account availability filtering
|
||||
5. For chat: `handleChatCore` — format detection, translation, cache check, idempotency check
|
||||
6. Provider executor sends upstream request
|
||||
7. Response translated back to client format (chat) or returned as-is (embeddings/images/audio)
|
||||
8. Usage/logging recorded
|
||||
9. Fallback applies on errors according to combo rules
|
||||
|
||||
Пълна справка за архитектурата: [link](ARCHITECTURE.md)
|
||||
Full architecture reference: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## Удостоверяване
|
||||
## Authentication
|
||||
|
||||
- Маршрутите на таблото за управление (`/dashboard/*`) използват бисквитка `auth_token`
|
||||
- Входът използва запазен хеш на паролата; връщане към `INITIAL_PASSWORD`
|
||||
- `requireLogin` превключваем чрез `/api/settings/require-login`
|
||||
- `/v1/*` маршрутите по избор изискват Bearer API ключ, когато `REQUIRE_API_KEY=true`
|
||||
- Dashboard routes (`/dashboard/*`) use `auth_token` cookie
|
||||
- Login uses saved password hash; fallback to `INITIAL_PASSWORD`
|
||||
- `requireLogin` toggleable via `/api/settings/require-login`
|
||||
- `/v1/*` routes optionally require Bearer API key when `REQUIRE_API_KEY=true`
|
||||
|
||||
@@ -1,71 +1,75 @@
|
||||
# Архитектура OmniRoute
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/ARCHITECTURE.md) · 🇪🇸 [es](../es/ARCHITECTURE.md) · 🇫🇷 [fr](../fr/ARCHITECTURE.md) · 🇩🇪 [de](../de/ARCHITECTURE.md) · 🇮🇹 [it](../it/ARCHITECTURE.md) · 🇷🇺 [ru](../ru/ARCHITECTURE.md) · 🇨🇳 [zh-CN](../zh-CN/ARCHITECTURE.md) · 🇯🇵 [ja](../ja/ARCHITECTURE.md) · 🇰🇷 [ko](../ko/ARCHITECTURE.md) · 🇸🇦 [ar](../ar/ARCHITECTURE.md) · 🇮🇳 [in](../in/ARCHITECTURE.md) · 🇹🇭 [th](../th/ARCHITECTURE.md) · 🇻🇳 [vi](../vi/ARCHITECTURE.md) · 🇮🇩 [id](../id/ARCHITECTURE.md) · 🇲🇾 [ms](../ms/ARCHITECTURE.md) · 🇳🇱 [nl](../nl/ARCHITECTURE.md) · 🇵🇱 [pl](../pl/ARCHITECTURE.md) · 🇸🇪 [sv](../sv/ARCHITECTURE.md) · 🇳🇴 [no](../no/ARCHITECTURE.md) · 🇩🇰 [da](../da/ARCHITECTURE.md) · 🇫🇮 [fi](../fi/ARCHITECTURE.md) · 🇵🇹 [pt](../pt/ARCHITECTURE.md) · 🇷🇴 [ro](../ro/ARCHITECTURE.md) · 🇭🇺 [hu](../hu/ARCHITECTURE.md) · 🇧🇬 [bg](../bg/ARCHITECTURE.md) · 🇸🇰 [sk](../sk/ARCHITECTURE.md) · 🇺🇦 [uk-UA](../uk-UA/ARCHITECTURE.md) · 🇮🇱 [he](../he/ARCHITECTURE.md) · 🇵🇭 [phi](../phi/ARCHITECTURE.md)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](../es/ARCHITECTURE.md) | 🇫🇷 [Français](../fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](../it/ARCHITECTURE.md) | 🇷🇺 [Русский](../ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](../zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](../de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](../in/ARCHITECTURE.md) | 🇹🇭 [ไทย](../th/ARCHITECTURE.md) | 🇺🇦 [Українська](../uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](../ar/ARCHITECTURE.md) | 🇯🇵 [日本語](../ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](../vi/ARCHITECTURE.md) | 🇧🇬 [Български](../bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](../da/ARCHITECTURE.md) | 🇫🇮 [Suomi](../fi/ARCHITECTURE.md) | 🇮🇱 [עברית](../he/ARCHITECTURE.md) | 🇭🇺 [Magyar](../hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](../id/ARCHITECTURE.md) | 🇰🇷 [한국어](../ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](../ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](../nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](../no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](../pt/ARCHITECTURE.md) | 🇷🇴 [Română](../ro/ARCHITECTURE.md) | 🇵🇱 [Polski](../pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](../sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](../sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](../phi/ARCHITECTURE.md)
|
||||
---
|
||||
|
||||
_Последна актуализация: 2026-02-18_
|
||||
# OmniRoute Architecture
|
||||
|
||||
## Резюме
|
||||
🌐 **Languages:** 🇺🇸 [English](ARCHITECTURE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵 [日本語](i18n/ja/ARCHITECTURE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dansk](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [Magyar](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nederlands](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipino](i18n/phi/ARCHITECTURE.md)
|
||||
|
||||
OmniRoute е локален AI маршрутизиращ шлюз и табло за управление, изградено на Next.js.
|
||||
Той осигурява една крайна точка, съвместима с OpenAI (`/v1/*`) и маршрутизира трафика през множество доставчици нагоре по веригата с превод, резервен вариант, опресняване на токени и проследяване на използването.
|
||||
_Last updated: 2026-03-04_
|
||||
|
||||
Основни възможности:
|
||||
## Executive Summary
|
||||
|
||||
- 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/`)
|
||||
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:
|
||||
|
||||
- Маршрутите на приложението Next.js под `src/app/api/*` прилагат както API на таблото за управление, така и API за съвместимост
|
||||
- Споделено SSE/маршрутизиращо ядро в `src/sse/*` + `open-sse/*` обработва изпълнението на доставчика, превода, стрийминг, резервен вариант и използване
|
||||
- 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
|
||||
|
||||
- Време за изпълнение на локален шлюз
|
||||
- API за управление на таблото
|
||||
- Удостоверяване на доставчика и опресняване на токена
|
||||
- Заявка за превод и SSE стрийминг
|
||||
- Локално състояние + постоянство на използване
|
||||
- Допълнителна синхронизация в облака
|
||||
## Scope and Boundaries
|
||||
|
||||
### Извън обхвата
|
||||
### In Scope
|
||||
|
||||
- Внедряване на облачна услуга зад `NEXT_PUBLIC_CLOUD_URL`
|
||||
- SLA/контролна равнина на доставчика извън локалния процес
|
||||
- Самите външни CLI двоични файлове (Claude CLI, Codex CLI и т.н.)
|
||||
- Local gateway runtime
|
||||
- Dashboard management APIs
|
||||
- Provider authentication and token refresh
|
||||
- Request translation and SSE streaming
|
||||
- Local state + usage persistence
|
||||
- Optional cloud sync orchestration
|
||||
|
||||
## Системен контекст на високо ниво
|
||||
### Out of Scope
|
||||
|
||||
- Cloud service implementation behind `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Provider SLA/control plane outside local process
|
||||
- External CLI binaries themselves (Claude CLI, Codex CLI, etc.)
|
||||
|
||||
## High-Level System Context
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -81,8 +85,8 @@ flowchart LR
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(db.json)]
|
||||
UDB[(usage.json + log.txt)]
|
||||
DB[(storage.sqlite)]
|
||||
UDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
@@ -113,151 +117,152 @@ flowchart LR
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## Основни компоненти по време на изпълнение
|
||||
## Core Runtime Components
|
||||
|
||||
## 1) API и слой за маршрутизиране (Маршрути на приложението Next.js)
|
||||
## 1) API and Routing Layer (Next.js App Routes)
|
||||
|
||||
Основни директории:
|
||||
Main directories:
|
||||
|
||||
- `src/app/api/v1/*` и `src/app/api/v1beta/*` за API за съвместимост
|
||||
- `src/app/api/*` за API за управление/конфигуриране
|
||||
- Следващото пренаписване в `next.config.mjs` преобразува `/v1/*` в `/api/v1/*`
|
||||
- `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/*`
|
||||
|
||||
Важни пътища за съвместимост:
|
||||
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` — включва потребителски модели с `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/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/messages/count_tokens/route.ts`
|
||||
- `src/app/api/v1/providers/[provider]/chat/completions/route.ts` — специален чат за всеки доставчик
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — специални вграждания за всеки доставчик
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — специални изображения за всеки доставчик
|
||||
- `src/app/api/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/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
Домейни за управление:
|
||||
Management domains:
|
||||
|
||||
- Удостоверяване/настройки: `src/app/api/auth/*`, `src/app/api/settings/*`
|
||||
- Доставчици/връзки: `src/app/api/providers*`
|
||||
- Възли на доставчик: `src/app/api/provider-nodes*`
|
||||
- Персонализирани модели: `src/app/api/provider-models` (GET/POST/DELETE)
|
||||
- Каталог с модели: `src/app/api/models/catalog` (GET)
|
||||
- Прокси конфигурация: `src/app/api/settings/proxy` (GET/PUT/DELETE) + `src/app/api/settings/proxy/test` (POST)
|
||||
- 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)
|
||||
- OAuth: `src/app/api/oauth/*`
|
||||
- Ключове/псевдоними/комбота/цени: `src/app/api/keys*`, `src/app/api/models/alias`, `src/app/api/combos*`, `src/app/api/pricing`
|
||||
- Използване: `src/app/api/usage/*`
|
||||
- Синхронизиране/облак: `src/app/api/sync/*`, `src/app/api/cloud/*`
|
||||
- Помощни инструменти за CLI: `src/app/api/cli-tools/*`
|
||||
- IP филтър: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Бюджет за мислене: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- Системна подкана: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Сесии: `src/app/api/sessions` (GET)
|
||||
- Ограничения на скоростта: `src/app/api/rate-limits` (GET)
|
||||
- Устойчивост: `src/app/api/resilience` (GET/PATCH) — профили на доставчик, прекъсвач, състояние на ограничение на скоростта
|
||||
- Нулиране на устойчивостта: `src/app/api/resilience/reset` (POST) — нулиране на прекъсвачи + охлаждане
|
||||
- Кеш статистики: `src/app/api/cache/stats` (ПОЛУЧАВАНЕ/ИЗТРИВАНЕ)
|
||||
- Наличност на модела: `src/app/api/models/availability` (GET/POST)
|
||||
- Телеметрия: `src/app/api/telemetry/summary` (GET)
|
||||
- Бюджет: `src/app/api/usage/budget` (GET/POST)
|
||||
- Резервни вериги: `src/app/api/fallback/chains` (GET/POST/DELETE)
|
||||
- Одит за съответствие: `src/app/api/compliance/audit-log` (GET)
|
||||
- Стойности: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Правила: `src/app/api/policies` (GET/POST)
|
||||
- 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)
|
||||
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Policies: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + ядро за превод
|
||||
## 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`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Тънка обвивка: `src/lib/oauth/providers.ts` — повторно експортиране от отделни модули
|
||||
- Registry index: `src/lib/oauth/providers/index.ts`
|
||||
- Individual providers: `claude.ts`, `codex.ts`, `gemini.ts`, `antigravity.ts`, `iflow.ts`, `qwen.ts`, `kimi-coding.ts`, `github.ts`, `kiro.ts`, `cursor.ts`, `kilocode.ts`, `cline.ts`
|
||||
- Thin wrapper: `src/lib/oauth/providers.ts` — re-exports from individual modules
|
||||
|
||||
## 3) Слой за устойчивост
|
||||
## 3) Persistence Layer
|
||||
|
||||
Основно състояние DB:
|
||||
Primary state DB (SQLite):
|
||||
|
||||
- `src/lib/localDb.ts`
|
||||
- файл: `${DATA_DIR}/db.json` (или `$XDG_CONFIG_HOME/omniroute/db.json`, когато е зададено, в противен случай `~/.omniroute/db.json`)
|
||||
- обекти: providerConnections, providerNodes, modelAliases, комбинации, apiKeys, настройки, ценообразуване, **customModels**, **proxyConfig**, **ipFilter**, **thinkingBudget**, **systemPrompt**
|
||||
- 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**
|
||||
|
||||
DB за използване:
|
||||
Usage persistence:
|
||||
|
||||
- `src/lib/usageDb.ts`
|
||||
- файлове: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- следва същата основна политика за директория като `localDb` (`DATA_DIR`, след това `XDG_CONFIG_HOME/omniroute`, когато е зададено)
|
||||
- разложен на фокусирани подмодули: `migrations.ts`, `usageHistory.ts`, `costCalculator.ts`, `usageStats.ts`, `callLogs.ts`
|
||||
- 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
|
||||
|
||||
DB на състоянието на домейна (SQLite):
|
||||
Domain State DB (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD операции за състояние на домейна
|
||||
- Таблици (създадени в `src/lib/db/core.ts`): `domain_fallback_chains`, `domain_budgets`, `domain_cost_history`, `domain_lockout_state`, `domain_circuit_breakers`
|
||||
- Модел на кеша за запис: Картите в паметта са авторитетни по време на изпълнение; мутациите се записват синхронно в SQLite; състоянието се възстановява от DB при студен старт
|
||||
- `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) Удостоверяване + повърхности за сигурност
|
||||
## 4) Auth + Security Surfaces
|
||||
|
||||
- Удостоверяване на бисквитките на таблото за управление: `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` (конфигурируем за всеки доставчик или глобално)
|
||||
- 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) Синхронизиране в облак
|
||||
## 5) Cloud Sync
|
||||
|
||||
- Инициализация на планировчика: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
||||
- Периодична задача: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Контролен маршрут: `src/app/api/sync/cloud/route.ts`
|
||||
- Scheduler init: `src/lib/initCloudSync.ts`, `src/shared/services/initializeCloudSync.ts`
|
||||
- Periodic task: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Control route: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Жизнен цикъл на заявка (`/v1/chat/completions`)
|
||||
## Request Lifecycle (`/v1/chat/completions`)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -304,7 +309,7 @@ sequenceDiagram
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## Комбо + Резервен поток на акаунт
|
||||
## Combo + Account Fallback Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -334,9 +339,9 @@ flowchart TD
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Резервните решения се управляват от `open-sse/services/accountFallback.ts` с помощта на кодове за състояние и евристика за съобщения за грешка.
|
||||
Fallback decisions are driven by `open-sse/services/accountFallback.ts` using status codes and error-message heuristics.
|
||||
|
||||
## Жизнен цикъл на внедряване на OAuth и опресняване на токени
|
||||
## OAuth Onboarding and Token Refresh Lifecycle
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -366,9 +371,9 @@ sequenceDiagram
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Опресняването по време на трафик на живо се изпълнява вътре в `open-sse/handlers/chatCore.ts` чрез изпълнител `refreshCredentials()`.
|
||||
Refresh during live traffic is executed inside `open-sse/handlers/chatCore.ts` via executor `refreshCredentials()`.
|
||||
|
||||
## Жизнен цикъл на Cloud Sync (Активиране / Синхронизиране / Деактивиране)
|
||||
## Cloud Sync Lifecycle (Enable / Sync / Disable)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -400,9 +405,9 @@ sequenceDiagram
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Периодичното синхронизиране се задейства от `CloudSyncScheduler`, когато облакът е активиран.
|
||||
Periodic sync is triggered by `CloudSyncScheduler` when cloud is enabled.
|
||||
|
||||
## Модел на данни и карта за съхранение
|
||||
## Data Model and Storage Map
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
@@ -503,14 +508,14 @@ erDiagram
|
||||
}
|
||||
```
|
||||
|
||||
Файлове за физическо съхранение:
|
||||
Physical storage files:
|
||||
|
||||
- основно състояние: `${DATA_DIR}/db.json` (или `$XDG_CONFIG_HOME/omniroute/db.json`, когато е зададено, в противен случай `~/.omniroute/db.json`)
|
||||
- статистика за използване: `${DATA_DIR}/usage.json`
|
||||
- Редове на заявката: `${DATA_DIR}/log.txt`
|
||||
- незадължителни сесии за преводач/заявка за отстраняване на грешки: `<repo>/logs/...`
|
||||
- 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
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -522,8 +527,8 @@ flowchart LR
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(db.json)]
|
||||
UsageDB[(usage.json/log.txt)]
|
||||
MainDB[(storage.sqlite)]
|
||||
UsageDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
@@ -541,241 +546,242 @@ flowchart LR
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## Съпоставяне на модул (критично за вземане на решения)
|
||||
## Module Mapping (Decision-Critical)
|
||||
|
||||
### Модули за маршрут и API
|
||||
### Route and API Modules
|
||||
|
||||
- `src/app/api/v1/*`, `src/app/api/v1beta/*`: API за съвместимост
|
||||
- `src/app/api/v1/providers/[provider]/*`: специални маршрути за всеки доставчик (чат, вграждания, изображения)
|
||||
- `src/app/api/providers*`: доставчик CRUD, валидиране, тестване
|
||||
- `src/app/api/provider-nodes*`: персонализирано съвместимо управление на възли
|
||||
- `src/app/api/provider-models`: персонализирано управление на модела (CRUD)
|
||||
- `src/app/api/models/catalog`: пълен модел каталог API (всички типове групирани по доставчик)
|
||||
- `src/app/api/oauth/*`: OAuth/код на устройство протича
|
||||
- `src/app/api/keys*`: жизнен цикъл на локален API ключ
|
||||
- `src/app/api/models/alias`: управление на псевдоними
|
||||
- `src/app/api/combos*`: резервно комбо управление
|
||||
- `src/app/api/pricing`: ценообразуване отменя за изчисляване на разходите
|
||||
- `src/app/api/settings/proxy`: конфигурация на прокси (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test`: тест за изходяща прокси връзка (POST)
|
||||
- `src/app/api/usage/*`: API за използване и регистрационни файлове
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*`: облачно синхронизиране и помощници в облака
|
||||
- `src/app/api/cli-tools/*`: локални писатели/контролери на CLI конфигурация
|
||||
- `src/app/api/settings/ip-filter`: списък с разрешени/блокирани IP адреси (GET/PUT)
|
||||
- `src/app/api/settings/thinking-budget`: конфигурация на бюджета на мислещ токен (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt`: глобална системна подкана (GET/PUT)
|
||||
- `src/app/api/sessions`: списък с активни сесии (GET)
|
||||
- `src/app/api/rate-limits`: състояние на ограничение на скоростта на сметка (GET)
|
||||
- `src/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)
|
||||
|
||||
### Ядро за маршрутизиране и изпълнение
|
||||
### Routing and Execution Core
|
||||
|
||||
- `src/sse/handlers/chat.ts`: анализ на заявка, комбо обработка, цикъл за избор на акаунт
|
||||
- `open-sse/handlers/chatCore.ts`: превод, изпращане на изпълнителя, обработка на повторен опит/опресняване, настройка на потока
|
||||
- `open-sse/executors/*`: специфично за доставчика поведение на мрежата и формата
|
||||
- `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
|
||||
|
||||
### Регистър за преводи и конвертори на формати
|
||||
### Translation Registry and Format Converters
|
||||
|
||||
- `open-sse/translator/index.ts`: регистър на преводача и оркестрация
|
||||
- Заявка за преводачи: `open-sse/translator/request/*`
|
||||
- Преводачи на отговори: `open-sse/translator/response/*`
|
||||
- Константи на формата: `open-sse/translator/formats.ts`
|
||||
- `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`
|
||||
|
||||
### Постоянство
|
||||
### Persistence
|
||||
|
||||
- `src/lib/localDb.ts`: постоянна конфигурация/състояние
|
||||
- `src/lib/usageDb.ts`: хронология на използването и регистрационни файлове на текущи заявки
|
||||
- `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
|
||||
|
||||
## Покритие на изпълнител на доставчик (стратегически модел)
|
||||
## Provider Executor Coverage (Strategy Pattern)
|
||||
|
||||
Всеки доставчик има специализиран изпълнител, разширяващ `BaseExecutor` (в `open-sse/executors/base.ts`), който осигурява изграждане на URL адрес, изграждане на заглавка, повторен опит с експоненциално забавяне, кукички за опресняване на идентификационни данни и метода за оркестрация `execute()`.
|
||||
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.
|
||||
|
||||
| Изпълнител | Доставчик(и) | Специална обработка |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Конфигурация на динамичен URL/заглавие за доставчик |
|
||||
| `AntigravityExecutor` | Google Антигравитация | Идентификационни номера на персонализирани проекти/сесии, повторен опит след анализ |
|
||||
| `CodexExecutor` | OpenAI Codex | Вкарва системни инструкции, налага усилие за разсъждение |
|
||||
| `CursorExecutor` | Курсор IDE | ConnectRPC протокол, Protobuf кодиране, подписване на заявка чрез контролна сума |
|
||||
| `GithubExecutor` | Копилот на GitHub | Опресняване на Copilot token, заглавки, имитиращи VSCode |
|
||||
| `KiroExecutor` | AWS CodeWhisperer/Киро | AWS EventStream двоичен формат → SSE конвертиране |
|
||||
| `GeminiCLIExecutor` | Gemini CLI | Цикъл на опресняване на Google OAuth токен |
|
||||
| Executor | Provider(s) | Special Handling |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------- |
|
||||
| `DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, 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 |
|
||||
|
||||
Всички други доставчици (включително персонализирани съвместими възли) използват `DefaultExecutor`.
|
||||
All other providers (including custom compatible nodes) use the `DefaultExecutor`.
|
||||
|
||||
## Матрица за съвместимост на доставчика
|
||||
## Provider Compatibility Matrix
|
||||
|
||||
| Доставчик | Формат | Удостоверяване | Поток | Непоточно | Опресняване на токена | API за използване |
|
||||
| ----------------- | --------------- | ------------------------------ | ---------------- | --------- | --------------------- | ---------------------------- |
|
||||
| Клод | Клод | API ключ / OAuth | ✅ | ✅ | ✅ | ⚠️ Само администратор |
|
||||
| Близнаци | близнаци | API ключ / OAuth | ✅ | ✅ | ✅ | ⚠️ Облачна конзола |
|
||||
| Gemini CLI | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Облачна конзола |
|
||||
| Антигравитация | антигравитация | OAuth | ✅ | ✅ | ✅ | ✅ API с пълна квота |
|
||||
| OpenAI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Кодекс | openai-отговори | OAuth | ✅ принуден | ❌ | ✅ | ✅ Ограничения на скоростта |
|
||||
| Копилот на GitHub | openai | OAuth + Copilot Token | ✅ | ✅ | ✅ | ✅ Моментни снимки на квоти |
|
||||
| Курсор | курсор | Персонализирана контролна сума | ✅ | ✅ | ❌ | ❌ |
|
||||
| Киро | киро | AWS SSO OIDC | ✅ (EventStream) | ❌ | ✅ | ✅ Ограничения за използване |
|
||||
| Куен | openai | OAuth | ✅ | ✅ | ✅ | ⚠️ По заявка |
|
||||
| iFlow | openai | OAuth (основен) | ✅ | ✅ | ✅ | ⚠️ По заявка |
|
||||
| OpenRouter | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| GLM/Кими/МиниМакс | Клод | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| DeepSeek | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Groq | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| xAI (Grok) | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Мистрал | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Недоумение | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Заедно AI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Фойерверки AI | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Мозъци | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| Cohere | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| NVIDIA NIM | openai | API ключ | ✅ | ✅ | ❌ | ❌ |
|
||||
| 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 |
|
||||
| iFlow | 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 чат/Отговори
|
||||
- Клод
|
||||
- Gemini/Gemini-CLI/Антигравитационен плик
|
||||
- Киро
|
||||
- Курсор
|
||||
- OpenAI chat/Responses
|
||||
- Claude
|
||||
- Gemini/Gemini-CLI/Antigravity envelope
|
||||
- Kiro
|
||||
- Cursor
|
||||
|
||||
Преводите използват **OpenAI като хъб формат** — всички реализации преминават през OpenAI като междинен:
|
||||
Translations use **OpenAI as the hub format** — all conversions go through OpenAI as intermediate:
|
||||
|
||||
```
|
||||
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:
|
||||
|
||||
- **Дефектификация на отговора** — Премахва нестандартните полета от отговорите във формат OpenAI (както стрийминг, така и без стрийминг), за да се гарантира стриктно съответствие с SDK
|
||||
- **Нормализиране на ролята** — Преобразува `developer` → `system` за цели, които не са OpenAI; обединява `system` → `user` за модели, които отхвърлят системната роля (GLM, ERNIE)
|
||||
- **Извличане на мислен етикет** — Анализира `<think>...</think>` блокове от съдържание в поле `reasoning_content`
|
||||
- **Структуриран изход** — Преобразува OpenAI `response_format.json_schema` в `responseMimeType` + `responseSchema` на Gemini
|
||||
- **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`
|
||||
|
||||
## Поддържани API крайни точки
|
||||
## Supported API Endpoints
|
||||
|
||||
| Крайна точка | Формат | Манипулатор |
|
||||
| -------------------------------------------------- | ------------------------- | ------------------------------------------------------------------ |
|
||||
| `POST /v1/chat/completions` | OpenAI чат | `src/sse/handlers/chat.ts` |
|
||||
| `POST /v1/messages` | Съобщения на Клод | Същият манипулатор (автоматично разпознат) |
|
||||
| `POST /v1/responses` | OpenAI отговори | `open-sse/handlers/responsesHandler.ts` |
|
||||
| `POST /v1/embeddings` | OpenAI вграждания | `open-sse/handlers/embeddings.ts` |
|
||||
| `GET /v1/embeddings` | Списък на модели | API маршрут |
|
||||
| `POST /v1/images/generations` | OpenAI изображения | `open-sse/handlers/imageGeneration.ts` |
|
||||
| `GET /v1/images/generations` | Списък на модели | API маршрут |
|
||||
| `POST /v1/providers/{provider}/chat/completions` | OpenAI чат | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/providers/{provider}/embeddings` | OpenAI вграждания | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/providers/{provider}/images/generations` | OpenAI изображения | Специализиран за всеки доставчик с валидиране на модел |
|
||||
| `POST /v1/messages/count_tokens` | Клод Токен Брой | API маршрут |
|
||||
| `GET /v1/models` | Списък с модели на OpenAI | API маршрут (чат + вграждане + изображение + потребителски модели) |
|
||||
| `GET /api/models/catalog` | Каталог | Всички модели, групирани по доставчик + тип |
|
||||
| `POST /v1beta/models/*:streamGenerateContent` | Родом от Близнаци | API маршрут |
|
||||
| `GET/PUT/DELETE /api/settings/proxy` | Прокси конфигурация | Конфигурация на мрежов прокси |
|
||||
| `POST /api/settings/proxy/test` | Прокси връзка | Крайна точка на прокси тест за изправност/свързаност |
|
||||
| `GET/POST/DELETE /api/provider-models` | Персонализирани модели | Персонализирано управление на модели за всеки доставчик |
|
||||
| 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` | Custom Models | Custom model management per provider |
|
||||
|
||||
## Обходен манипулатор
|
||||
## Bypass Handler
|
||||
|
||||
Обходният манипулатор (`open-sse/utils/bypassHandler.ts`) прихваща известни заявки за „изхвърляне“ от Claude CLI — пингове за загряване, извличане на заглавия и преброяване на токени — и връща **фалшив отговор**, без да консумира токени на доставчика нагоре по веригата. Това се задейства само когато `User-Agent` съдържа `claude-cli`.
|
||||
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
|
||||
|
||||
Регистраторът на заявки (`open-sse/utils/requestLogger.ts`) осигурява 7-етапен конвейер за регистриране на грешки, деактивиран по подразбиране, активиран чрез `ENABLE_REQUEST_LOGS=true`:
|
||||
The request logger (`open-sse/utils/requestLogger.ts`) provides a 7-stage debug logging pipeline, disabled by default, enabled via `ENABLE_REQUEST_LOGS=true`:
|
||||
|
||||
```
|
||||
1_req_client.json → 2_req_source.json → 3_req_openai.json → 4_req_target.json
|
||||
→ 5_res_provider.txt → 6_res_openai.txt → 7_res_client.txt
|
||||
```
|
||||
|
||||
Файловете се записват в `<repo>/logs/<session>/` за всяка сесия на заявка.
|
||||
Files are written to `<repo>/logs/<session>/` for each request session.
|
||||
|
||||
## Режими на отказ и устойчивост
|
||||
## Failure Modes and Resilience
|
||||
|
||||
## 1) Наличност на акаунт/доставчик
|
||||
## 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) Изтичане на токена
|
||||
## 2) Token Expiry
|
||||
|
||||
- предварителна проверка и опресняване с повторен опит за опресняващи доставчици
|
||||
- 401/403 повторен опит след опит за опресняване в основния път
|
||||
- pre-check and refresh with retry for refreshable providers
|
||||
- 401/403 retry after refresh attempt in core path
|
||||
|
||||
## 3) Безопасност на потока
|
||||
## 3) Stream Safety
|
||||
|
||||
- контролер на потоци, който се изключва
|
||||
- поток за превод с промиване в края на потока и обработка на `[DONE]`
|
||||
- резервна оценка на използването, когато липсват метаданни за използване на доставчика
|
||||
- disconnect-aware stream controller
|
||||
- translation stream with end-of-stream flush and `[DONE]` handling
|
||||
- usage estimation fallback when provider usage metadata is missing
|
||||
|
||||
## 4) Влошаване на облачната синхронизация
|
||||
## 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
|
||||
|
||||
## 5) Цялост на данните
|
||||
## 5) Data Integrity
|
||||
|
||||
- Миграция/поправка на DB форма за липсващи ключове
|
||||
- повредени предпазни мерки за нулиране на JSON за localDb и usageDb
|
||||
- SQLite schema migrations and auto-upgrade hooks at startup
|
||||
- legacy JSON → SQLite migration compatibility path
|
||||
|
||||
## Наблюдаемост и оперативни сигнали
|
||||
## Observability and Operational Signals
|
||||
|
||||
Източници на видимост по време на изпълнение:
|
||||
Runtime visibility sources:
|
||||
|
||||
- регистрационни файлове на конзолата от `src/sse/utils/logger.ts`
|
||||
- агрегати за използване на заявка в `usage.json`
|
||||
- влизане на състоянието на текстова заявка `log.txt`
|
||||
- незадължителни дълбоки регистрационни файлове за заявка/превод под `logs/`, когато `ENABLE_REQUEST_LOGS=true`
|
||||
- крайни точки за използване на таблото за управление (`/api/usage/*`) за потребление на UI
|
||||
- console logs from `src/sse/utils/logger.ts`
|
||||
- per-request usage aggregates in SQLite (`usage_history`, `call_logs`, `proxy_logs`)
|
||||
- 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
|
||||
|
||||
## Граници, чувствителни към сигурността
|
||||
## Security-Sensitive Boundaries
|
||||
|
||||
- JWT тайна (`JWT_SECRET`) защитава проверката/подписването на бисквитките на таблото за управление
|
||||
- Първоначалната резервна парола (`INITIAL_PASSWORD`, по подразбиране `123456`) трябва да бъде заменена при реални внедрявания
|
||||
- API ключ HMAC secret (`API_KEY_SECRET`) защитава генерирания локален формат на API ключ
|
||||
- Тайните на доставчика (API ключове/токени) се съхраняват в локалната база данни и трябва да бъдат защитени на ниво файлова система
|
||||
- Крайните точки за синхронизиране в облак разчитат на удостоверяване на API ключ + семантика на идентификатор на машина
|
||||
- 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:
|
||||
|
||||
- Приложение/удостоверяване: `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`
|
||||
- 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` и `localDb` сега споделят една и съща основна политика за директория (`DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute`) с мигриране на наследени файлове.
|
||||
2. `/api/v1/route.ts` връща списък със статичен модел и не е основният източник на модели, използван от `/v1/models`.
|
||||
3. Request logger записва пълни заглавки/тяло, когато е разрешено; третира регистрационната директория като чувствителна.
|
||||
4. Поведението в облака зависи от правилния `NEXT_PUBLIC_BASE_URL` и достижимостта на крайната точка на облака.
|
||||
5. Директорията `open-sse/` е публикувана като `@omniroute/open-sse` **npm workspace package**. Изходният код го импортира чрез `@omniroute/open-sse/...` (разрешено от Next.js `transpilePackages`). Пътищата на файловете в този документ все още използват името на директорията `open-sse/` за последователност.
|
||||
6. Диаграмите в таблото за управление използват **Recharts** (базирани на SVG) за достъпни, интерактивни аналитични визуализации (стълбовидни диаграми на използването на модела, таблици с разбивка на доставчиците с проценти на успех).
|
||||
7. E2E тестовете използват **Playwright** (`tests/e2e/`), изпълняват се чрез `npm run test:e2e`. Модулните тестове използват **Node.js test runner** (`tests/unit/`), изпълняват се чрез `npm run test:plan3`. Изходният код под `src/` е **TypeScript** (`.ts`/`.tsx`); работното пространство `open-sse/` остава JavaScript (`.js`).
|
||||
8. Страницата с настройки е организирана в 5 раздела: Сигурност, Маршрутизиране (6 глобални стратегии: първо попълване, кръгъл-робин, p2c, произволна, най-малко използвана, оптимизирана по отношение на разходите), Устойчивост (ограничения на скоростта за редактиране, прекъсвач, политики), AI (мислещ бюджет, системна подкана, кеш за подкана), Разширени (прокси).
|
||||
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
|
||||
|
||||
- Създаване от източник: `npm run build`
|
||||
- Изграждане на Docker изображение: `docker build -t omniroute .`
|
||||
- Стартирайте услугата и проверете:
|
||||
- Build from source: `npm run build`
|
||||
- Build Docker image: `docker build -t omniroute .`
|
||||
- Start service and verify:
|
||||
- `GET /api/settings`
|
||||
- `GET /api/v1/models`
|
||||
- CLI целеви базов URL трябва да бъде `http://<host>:20128/v1`, когато `PORT=20128`
|
||||
- CLI target base URL should be `http://<host>:20128/v1` when `PORT=20128`
|
||||
|
||||
67
docs/i18n/bg/AUTO-COMBO.md
Normal file
67
docs/i18n/bg/AUTO-COMBO.md
Normal file
@@ -0,0 +1,67 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/AUTO-COMBO.md) · 🇪🇸 [es](../es/AUTO-COMBO.md) · 🇫🇷 [fr](../fr/AUTO-COMBO.md) · 🇩🇪 [de](../de/AUTO-COMBO.md) · 🇮🇹 [it](../it/AUTO-COMBO.md) · 🇷🇺 [ru](../ru/AUTO-COMBO.md) · 🇨🇳 [zh-CN](../zh-CN/AUTO-COMBO.md) · 🇯🇵 [ja](../ja/AUTO-COMBO.md) · 🇰🇷 [ko](../ko/AUTO-COMBO.md) · 🇸🇦 [ar](../ar/AUTO-COMBO.md) · 🇮🇳 [in](../in/AUTO-COMBO.md) · 🇹🇭 [th](../th/AUTO-COMBO.md) · 🇻🇳 [vi](../vi/AUTO-COMBO.md) · 🇮🇩 [id](../id/AUTO-COMBO.md) · 🇲🇾 [ms](../ms/AUTO-COMBO.md) · 🇳🇱 [nl](../nl/AUTO-COMBO.md) · 🇵🇱 [pl](../pl/AUTO-COMBO.md) · 🇸🇪 [sv](../sv/AUTO-COMBO.md) · 🇳🇴 [no](../no/AUTO-COMBO.md) · 🇩🇰 [da](../da/AUTO-COMBO.md) · 🇫🇮 [fi](../fi/AUTO-COMBO.md) · 🇵🇹 [pt](../pt/AUTO-COMBO.md) · 🇷🇴 [ro](../ro/AUTO-COMBO.md) · 🇭🇺 [hu](../hu/AUTO-COMBO.md) · 🇧🇬 [bg](../bg/AUTO-COMBO.md) · 🇸🇰 [sk](../sk/AUTO-COMBO.md) · 🇺🇦 [uk-UA](../uk-UA/AUTO-COMBO.md) · 🇮🇱 [he](../he/AUTO-COMBO.md) · 🇵🇭 [phi](../phi/AUTO-COMBO.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute Auto-Combo Engine
|
||||
|
||||
> Self-managing model chains with adaptive scoring
|
||||
|
||||
## How It Works
|
||||
|
||||
The Auto-Combo Engine dynamically selects the best provider/model for each request using a **6-factor scoring function**:
|
||||
|
||||
| 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 |
|
||||
|
||||
## Mode Packs
|
||||
|
||||
| Pack | Focus | Key Weight |
|
||||
| :---------------------- | :----------- | :--------------- |
|
||||
| 🚀 **Ship Fast** | Speed | latencyInv: 0.35 |
|
||||
| 💰 **Cost Saver** | Economy | costInv: 0.40 |
|
||||
| 🎯 **Quality First** | Best model | taskFit: 0.40 |
|
||||
| 📡 **Offline Friendly** | Availability | quota: 0.40 |
|
||||
|
||||
## Self-Healing
|
||||
|
||||
- **Temporary exclusion**: Score < 0.2 → excluded for 5 min (progressive backoff, max 30 min)
|
||||
- **Circuit breaker awareness**: OPEN → auto-excluded; HALF_OPEN → probe requests
|
||||
- **Incident mode**: >50% OPEN → disable exploration, maximize stability
|
||||
- **Cooldown recovery**: After exclusion, first request is a "probe" with reduced timeout
|
||||
|
||||
## Bandit Exploration
|
||||
|
||||
5% of requests (configurable) are routed to random providers for exploration. Disabled in incident mode.
|
||||
|
||||
## API
|
||||
|
||||
```bash
|
||||
# Create auto-combo
|
||||
curl -X POST http://localhost:20128/api/combos/auto \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"id":"my-auto","name":"Auto Coder","candidatePool":["anthropic","google","openai"],"modePack":"ship-fast"}'
|
||||
|
||||
# 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).
|
||||
|
||||
## 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 |
|
||||
351
docs/i18n/bg/CLI-TOOLS.md
Normal file
351
docs/i18n/bg/CLI-TOOLS.md
Normal file
@@ -0,0 +1,351 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CLI-TOOLS.md) · 🇧🇷 [pt-BR](../pt-BR/CLI-TOOLS.md) · 🇪🇸 [es](../es/CLI-TOOLS.md) · 🇫🇷 [fr](../fr/CLI-TOOLS.md) · 🇩🇪 [de](../de/CLI-TOOLS.md) · 🇮🇹 [it](../it/CLI-TOOLS.md) · 🇷🇺 [ru](../ru/CLI-TOOLS.md) · 🇨🇳 [zh-CN](../zh-CN/CLI-TOOLS.md) · 🇯🇵 [ja](../ja/CLI-TOOLS.md) · 🇰🇷 [ko](../ko/CLI-TOOLS.md) · 🇸🇦 [ar](../ar/CLI-TOOLS.md)
|
||||
|
||||
# Ръководство за настройка на CLI инструменти — OmniRoute
|
||||
|
||||
Това ръководство обяснява как да инсталирате и конфигурирате всички поддържани AI CLI инструменти за използване на **OmniRoute** като унифициран бекенд.
|
||||
|
||||
This guide explains how to install and configure all supported AI coding CLI tools
|
||||
to use **OmniRoute** as the unified backend, giving you centralized key management,
|
||||
cost tracking, model switching, and request logging across every tool.
|
||||
|
||||
---
|
||||
|
||||
## How It Works
|
||||
|
||||
```
|
||||
Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
|
||||
│
|
||||
▼ (all point to OmniRoute)
|
||||
http://YOUR_SERVER:20128/v1
|
||||
│
|
||||
▼ (OmniRoute routes to the right provider)
|
||||
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)
|
||||
|
||||
---
|
||||
|
||||
## Supported Tools
|
||||
|
||||
| Tool | Command | Type | Install Method |
|
||||
| ---------------- | ------------------- | ----------------- | -------------- |
|
||||
| **Claude Code** | `claude` | CLI | npm |
|
||||
| **OpenAI Codex** | `codex` | CLI | npm |
|
||||
| **Gemini CLI** | `gemini` | CLI | npm |
|
||||
| **OpenCode** | `opencode` | CLI | npm |
|
||||
| **Cline** | `cline` | CLI + VS Code ext | npm |
|
||||
| **KiloCode** | `kilocode` / `kilo` | CLI + VS Code ext | npm |
|
||||
| **Continue** | guide-based | VS Code ext | VS Code |
|
||||
| **Kiro CLI** | `kiro-cli` | CLI | curl installer |
|
||||
| **Cursor** | `cursor` | Desktop app | Download |
|
||||
| **Droid** | web-based | Built-in agent | OmniRoute |
|
||||
| **OpenClaw** | web-based | Built-in agent | OmniRoute |
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
> Your key looks like: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
|
||||
## Step 2 — Install CLI Tools
|
||||
|
||||
All npm-based tools require Node.js 18+:
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
npm install -g @openai/codex
|
||||
|
||||
# Gemini CLI (Google)
|
||||
npm install -g @google/gemini-cli
|
||||
|
||||
# OpenCode
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
npm install -g kilecode
|
||||
|
||||
# Kiro CLI (Amazon — requires curl + unzip)
|
||||
apt-get install -y unzip # on Debian/Ubuntu
|
||||
curl -fsSL https://cli.kiro.dev/install | bash
|
||||
export PATH="$HOME/.local/bin:$PATH" # add to ~/.bashrc
|
||||
```
|
||||
|
||||
**Verify:**
|
||||
|
||||
```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
gemini --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`:
|
||||
|
||||
```bash
|
||||
# OmniRoute Universal Endpoint
|
||||
export OPENAI_BASE_URL="http://localhost:20128/v1"
|
||||
export OPENAI_API_KEY="sk-your-omniroute-key"
|
||||
export ANTHROPIC_BASE_URL="http://localhost:20128/v1"
|
||||
export ANTHROPIC_API_KEY="sk-your-omniroute-key"
|
||||
export GEMINI_BASE_URL="http://localhost:20128/v1"
|
||||
export GEMINI_API_KEY="sk-your-omniroute-key"
|
||||
```
|
||||
|
||||
> For a **remote server** replace `localhost:20128` with the server IP or domain,
|
||||
> e.g. `http://192.168.0.15:20128`.
|
||||
|
||||
---
|
||||
|
||||
## Step 4 — Configure Each Tool
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
# Via CLI:
|
||||
claude config set --global api-base-url http://localhost:20128/v1
|
||||
|
||||
# Or create ~/.claude/settings.json:
|
||||
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
{
|
||||
"apiBaseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
|
||||
### Gemini CLI
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
|
||||
{
|
||||
"apiKey": "sk-your-omniroute-key",
|
||||
"baseUrl": "http://localhost:20128/v1"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `gemini "hello"`
|
||||
|
||||
---
|
||||
|
||||
### OpenCode
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
|
||||
### Cline (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.cline/data && cat > ~/.cline/data/globalState.json << EOF
|
||||
{
|
||||
"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**.
|
||||
|
||||
---
|
||||
|
||||
### KiloCode (CLI or VS Code)
|
||||
|
||||
**CLI mode:**
|
||||
|
||||
```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
|
||||
**VS Code settings:**
|
||||
|
||||
```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Or use the OmniRoute dashboard → **CLI Tools → KiloCode → Apply Config**.
|
||||
|
||||
---
|
||||
|
||||
### Continue (VS Code Extension)
|
||||
|
||||
Edit `~/.continue/config.yaml`:
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
model: auto
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
|
||||
Restart VS Code after editing.
|
||||
|
||||
---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
```bash
|
||||
# Login to your AWS/Kiro account:
|
||||
kiro-cli login
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 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.
|
||||
|
||||
Via GUI: **Settings → Models → OpenAI API Key**
|
||||
|
||||
- Base URL: `https://your-domain.com/v1`
|
||||
- API Key: your OmniRoute key
|
||||
|
||||
---
|
||||
|
||||
## Dashboard Auto-Configuration
|
||||
|
||||
The OmniRoute dashboard automates configuration for most tools:
|
||||
|
||||
1. Go to `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Expand any tool card
|
||||
3. Select your API key from the dropdown
|
||||
4. Click **Apply Config** (if tool is detected as installed)
|
||||
5. Or copy the generated config snippet manually
|
||||
|
||||
---
|
||||
|
||||
## Built-in Agents: Droid & OpenClaw
|
||||
|
||||
**Droid** and **OpenClaw** are AI agents built directly into OmniRoute — no installation needed.
|
||||
They run as internal routes and use OmniRoute's model routing automatically.
|
||||
|
||||
- Access: `http://localhost:20128/dashboard/agents`
|
||||
- Configure: same combos and providers as all other tools
|
||||
- No API key or CLI install required
|
||||
|
||||
---
|
||||
|
||||
## Available API Endpoints
|
||||
|
||||
| Endpoint | Description | Use For |
|
||||
| -------------------------- | ----------------------------- | --------------------------- |
|
||||
| `/v1/chat/completions` | 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 |
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| 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"` |
|
||||
|
||||
---
|
||||
|
||||
## Quick Setup Script (One Command)
|
||||
|
||||
```bash
|
||||
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
|
||||
OMNIROUTE_URL="http://localhost:20128/v1"
|
||||
OMNIROUTE_KEY="sk-your-omniroute-key"
|
||||
|
||||
npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode
|
||||
|
||||
# Kiro CLI
|
||||
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
|
||||
|
||||
# Write configs
|
||||
mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue
|
||||
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}"
|
||||
cat >> ~/.bashrc << EOF
|
||||
export OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
export OPENAI_API_KEY="$OMNIROUTE_KEY"
|
||||
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
|
||||
EOF
|
||||
|
||||
source ~/.bashrc
|
||||
echo "✅ All CLIs installed and configured for OmniRoute"
|
||||
```
|
||||
@@ -1,22 +1,26 @@
|
||||
# omniroute — Документация на кодовата база
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](../pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](../es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](../fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](../it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](../ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](../zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](../de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](../in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](../th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](../uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](../ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](../ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](../vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](../bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](../da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](../fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](../he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](../hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](../id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](../ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](../ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](../nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](../no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](../pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](../ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](../pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](../sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](../sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> Изчерпателно, удобно за начинаещи ръководство за **omniroute** прокси рутер с изкуствен интелект с множество доставчици.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/CODEBASE_DOCUMENTATION.md) · 🇪🇸 [es](../es/CODEBASE_DOCUMENTATION.md) · 🇫🇷 [fr](../fr/CODEBASE_DOCUMENTATION.md) · 🇩🇪 [de](../de/CODEBASE_DOCUMENTATION.md) · 🇮🇹 [it](../it/CODEBASE_DOCUMENTATION.md) · 🇷🇺 [ru](../ru/CODEBASE_DOCUMENTATION.md) · 🇨🇳 [zh-CN](../zh-CN/CODEBASE_DOCUMENTATION.md) · 🇯🇵 [ja](../ja/CODEBASE_DOCUMENTATION.md) · 🇰🇷 [ko](../ko/CODEBASE_DOCUMENTATION.md) · 🇸🇦 [ar](../ar/CODEBASE_DOCUMENTATION.md) · 🇮🇳 [in](../in/CODEBASE_DOCUMENTATION.md) · 🇹🇭 [th](../th/CODEBASE_DOCUMENTATION.md) · 🇻🇳 [vi](../vi/CODEBASE_DOCUMENTATION.md) · 🇮🇩 [id](../id/CODEBASE_DOCUMENTATION.md) · 🇲🇾 [ms](../ms/CODEBASE_DOCUMENTATION.md) · 🇳🇱 [nl](../nl/CODEBASE_DOCUMENTATION.md) · 🇵🇱 [pl](../pl/CODEBASE_DOCUMENTATION.md) · 🇸🇪 [sv](../sv/CODEBASE_DOCUMENTATION.md) · 🇳🇴 [no](../no/CODEBASE_DOCUMENTATION.md) · 🇩🇰 [da](../da/CODEBASE_DOCUMENTATION.md) · 🇫🇮 [fi](../fi/CODEBASE_DOCUMENTATION.md) · 🇵🇹 [pt](../pt/CODEBASE_DOCUMENTATION.md) · 🇷🇴 [ro](../ro/CODEBASE_DOCUMENTATION.md) · 🇭🇺 [hu](../hu/CODEBASE_DOCUMENTATION.md) · 🇧🇬 [bg](../bg/CODEBASE_DOCUMENTATION.md) · 🇸🇰 [sk](../sk/CODEBASE_DOCUMENTATION.md) · 🇺🇦 [uk-UA](../uk-UA/CODEBASE_DOCUMENTATION.md) · 🇮🇱 [he](../he/CODEBASE_DOCUMENTATION.md) · 🇵🇭 [phi](../phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
---
|
||||
|
||||
## 1. Какво е omniroute?
|
||||
# omniroute — Codebase Documentation
|
||||
|
||||
omniroute е **прокси рутер**, който се намира между AI клиенти (Claude CLI, Codex, Cursor IDE и др.) и AI доставчици (Anthropic, Google, OpenAI, AWS, GitHub и др.). Решава един голям проблем:
|
||||
🌐 **Languages:** 🇺🇸 [English](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵 [日本語](i18n/ja/CODEBASE_DOCUMENTATION.md) | 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dansk](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [Magyar](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nederlands](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugal)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipino](i18n/phi/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> **Различните AI клиенти говорят различни „езици“ (API формати) и различните доставчици на AI също очакват различни „езици“.** omniroute превежда автоматично между тях.
|
||||
|
||||
Мислете за това като за универсален преводач в Обединените нации - всеки делегат може да говори всеки език и преводачът го преобразува за всеки друг делегат.
|
||||
> A comprehensive, beginner-friendly guide to the **omniroute** multi-provider AI proxy router.
|
||||
|
||||
---
|
||||
|
||||
## 2. Преглед на архитектурата
|
||||
## 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
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
@@ -61,20 +65,20 @@ graph LR
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### Основен принцип: Превод на централно ниво
|
||||
### Core Principle: Hub-and-Spoke Translation
|
||||
|
||||
Всички преводи на формати преминават през **OpenAI формат като център**:
|
||||
All format translation passes through **OpenAI format as the hub**:
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
Това означава, че имате нужда само от **N преводачи** (по един на формат) вместо от **N²** (всяка двойка).
|
||||
This means you only need **N translators** (one per format) instead of **N²** (every pair).
|
||||
|
||||
---
|
||||
|
||||
## 3. Структура на проекта
|
||||
## 3. Project Structure
|
||||
|
||||
```
|
||||
omniroute/
|
||||
@@ -104,22 +108,22 @@ omniroute/
|
||||
|
||||
---
|
||||
|
||||
## 4. Разбивка модул по модул
|
||||
## 4. Module-by-Module Breakdown
|
||||
|
||||
### 4.1 Конфигурация (`open-sse/config/`)
|
||||
### 4.1 Config (`open-sse/config/`)
|
||||
|
||||
**Единственият източник на истина** за всички конфигурации на доставчика.
|
||||
The **single source of truth** for all provider configuration.
|
||||
|
||||
| Файл | Цел |
|
||||
| ----------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` обект с основни URL адреси, идентификационни данни за OAuth (по подразбиране), заглавки и системни подкани по подразбиране за всеки доставчик. Също така дефинира `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG` и `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Зарежда външни идентификационни данни от `data/provider-credentials.json` и ги обединява върху твърдо кодираните настройки по подразбиране в `PROVIDERS`. Пази тайните извън контрола на източника, като същевременно поддържа обратна съвместимост. |
|
||||
| `providerModels.ts` | Централен регистър на моделите: псевдоними на доставчика на карти → ID на модела. Функции като `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | Системни инструкции, инжектирани в заявките на Codex (ограничения за редактиране, правила на пясъчника, правила за одобрение). |
|
||||
| `defaultThinkingSignature.ts` | „Мислещи“ подписи по подразбиране за модели Claude и Gemini. |
|
||||
| `ollamaModels.ts` | Дефиниция на схема за локални модели Ollama (име, размер, семейство, квантуване). |
|
||||
| File | Purpose |
|
||||
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `constants.ts` | `PROVIDERS` object with base URLs, OAuth credentials (defaults), headers, and default system prompts for every provider. Also defines `HTTP_STATUS`, `ERROR_TYPES`, `COOLDOWN_MS`, `BACKOFF_CONFIG`, and `SKIP_PATTERNS`. |
|
||||
| `credentialLoader.ts` | Loads external credentials from `data/provider-credentials.json` and merges them over the hardcoded defaults in `PROVIDERS`. Keeps secrets out of source control while maintaining backwards compatibility. |
|
||||
| `providerModels.ts` | Central model registry: maps provider aliases → model IDs. Functions like `getModels()`, `getProviderByAlias()`. |
|
||||
| `codexInstructions.ts` | System instructions injected into Codex requests (editing constraints, sandbox rules, approval policies). |
|
||||
| `defaultThinkingSignature.ts` | Default "thinking" signatures for Claude and Gemini models. |
|
||||
| `ollamaModels.ts` | Schema definition for local Ollama models (name, size, family, quantization). |
|
||||
|
||||
#### Поток на зареждане на идентификационни данни
|
||||
#### Credential Loading Flow
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
@@ -142,9 +146,9 @@ flowchart TD
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Изпълнители (`open-sse/executors/`)
|
||||
### 4.2 Executors (`open-sse/executors/`)
|
||||
|
||||
Изпълнителите капсулират **специфична за доставчика логика**, използвайки **стратегически модел**. Всеки изпълнител замества основните методи, ако е необходимо.
|
||||
Executors encapsulate **provider-specific logic** using the **Strategy Pattern**. Each executor overrides base methods as needed.
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
@@ -194,32 +198,32 @@ classDiagram
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
| Изпълнител | Доставчик | Ключови специализации |
|
||||
| ---------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `base.ts` | — | Абстрактна база: изграждане на URL, заглавки, логика за повторен опит, опресняване на идентификационни данни |
|
||||
| `default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Генерично опресняване на OAuth токен за стандартни доставчици |
|
||||
| `antigravity.ts` | Google Cloud Code | Генериране на идентификатор на проект/сесия, резервен URL адрес с множество URL адреси, персонализирано анализиране на повторен опит от съобщения за грешка („нулиране след 2h7m23s“) |
|
||||
| `cursor.ts` | Курсор IDE | **Най-сложни**: SHA-256 контролна сума auth, Protobuf кодиране на заявка, двоичен EventStream → SSE отговор анализ |
|
||||
| `codex.ts` | OpenAI Codex | Вкарва системни инструкции, управлява нивата на мислене, премахва неподдържаните параметри |
|
||||
| `gemini-cli.ts` | Google Gemini CLI | Изграждане на персонализиран URL (`streamGenerateContent`), опресняване на Google OAuth токен |
|
||||
| `github.ts` | Копилот на GitHub | Система с двоен токен (GitHub OAuth + Copilot token), имитиране на заглавката на VSCode |
|
||||
| `kiro.ts` | AWS CodeWhisperer | Двоичен анализ на AWS EventStream, рамки за събития AMZN, оценка на токена |
|
||||
| `index.ts` | — | Фабрика: картографира името на доставчика → клас изпълнител, с резервен вариант по подразбиране |
|
||||
| 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 |
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Манипулатори (`open-sse/handlers/`)
|
||||
### 4.3 Handlers (`open-sse/handlers/`)
|
||||
|
||||
**Слоят за оркестрация** — координира превода, изпълнението, поточното предаване и обработката на грешки.
|
||||
The **orchestration layer** — coordinates translation, execution, streaming, and error handling.
|
||||
|
||||
| Файл | Цел |
|
||||
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `chatCore.ts` | **Централен оркестратор** (~600 реда). Обработва пълния жизнен цикъл на заявката: откриване на формат → превод → изпращане на изпълнител → стрийминг/не-стрийминг отговор → опресняване на токена → обработка на грешки → регистриране на използването. |
|
||||
| `responsesHandler.ts` | Адаптер за API за отговори на OpenAI: преобразува формата на отговорите → Завършвания на чат → изпраща до `chatCore` → конвертира SSE обратно във формат на отговорите. |
|
||||
| `embeddings.ts` | Манипулатор за генериране на вграждане: разрешава модел на вграждане → доставчик, изпраща до API на доставчика, връща съвместим с OpenAI отговор за вграждане. Поддържа 6+ доставчици. |
|
||||
| `imageGeneration.ts` | Манипулатор за генериране на изображения: разрешава модел на изображение → доставчик, поддържа режими, съвместими с OpenAI, Gemini-image (Антигравитация) и резервни (Nebius). Връща base64 или URL изображения. |
|
||||
| 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. |
|
||||
|
||||
#### Жизнен цикъл на заявка (chatCore.ts)
|
||||
#### Request Lifecycle (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -258,28 +262,28 @@ sequenceDiagram
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Услуги (`open-sse/services/`)
|
||||
### 4.4 Services (`open-sse/services/`)
|
||||
|
||||
Бизнес логика, която поддържа манипулаторите и изпълнителите.
|
||||
Business logic that supports the handlers and executors.
|
||||
|
||||
| Файл | Цел |
|
||||
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `provider.ts` | **Откриване на формат** (`detectFormat`): анализира структурата на тялото на заявката, за да идентифицира форматите Claude/OpenAI/Gemini/Antigravity/Responses (включва `max_tokens` евристика за Claude). Също така: изграждане на URL адреси, изграждане на заглавки, нормализиране на конфигурацията на мислене. Поддържа `openai-compatible-*` и `anthropic-compatible-*` динамични доставчици. |
|
||||
| `model.ts` | Разбор на низ на модел (`claude/model-name` → `{provider: "claude", model: "model-name"}`), разрешаване на псевдоними с откриване на сблъсък, дезинфекция на входа (отхвърля преминаване на пътя/контролни знаци) и разрешаване на информация за модела с поддръжка на асинхронно получаване на псевдоними. |
|
||||
| `accountFallback.ts` | Обработка на ограничение на скоростта: експоненциално забавяне (1s → 2s → 4s → макс. 2min), управление на изчакване на акаунта, класификация на грешките (кои грешки задействат резервно или не). |
|
||||
| `tokenRefresh.ts` | Опресняване на OAuth токена за **всеки доставчик**: Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (OAuth + Copilot dual-token), Kiro (AWS SSO OIDC + Social Auth). Включва кеш за дедупликация на обещание по време на полет и повторен опит с експоненциално забавяне. |
|
||||
| `combo.ts` | **Комбинирани модели**: вериги от резервни модели. Ако модел A се провали с допустима грешка за резервен вариант, опитайте модел B, след това C и т.н. Връща действителните кодове за състояние нагоре по веригата. |
|
||||
| `usage.ts` | Извлича данни за квоти/използване от API на доставчика (квоти на GitHub Copilot, квоти на модела на Antigravity, ограничения на скоростта на Codex, разбивки на използването на Kiro, настройки на Claude). |
|
||||
| `accountSelector.ts` | Интелигентен избор на акаунт с алгоритъм за точкуване: взема предвид приоритет, здравословно състояние, кръгова позиция и състояние на изчакване, за да избере оптималния акаунт за всяка заявка. |
|
||||
| `contextManager.ts` | Управление на жизнения цикъл на контекста на заявката: създава и проследява контекстни обекти на заявка с метаданни (идентификатор на заявка, времеви клейма, информация за доставчика) за отстраняване на грешки и регистриране. |
|
||||
| `ipFilter.ts` | IP-базиран контрол на достъпа: поддържа разрешени и блокирани режими. Валидира клиентския IP адрес спрямо конфигурирани правила, преди да обработи API заявки. |
|
||||
| `sessionManager.ts` | Проследяване на сесии с пръстов отпечатък на клиента: проследява активни сесии с помощта на хеширани клиентски идентификатори, следи броя на заявките и предоставя показатели за сесиите. |
|
||||
| `signatureCache.ts` | Кеш за дедупликация, базиран на подписи на заявки: предотвратява дублиране на заявки чрез кеширане на подписи на скорошни заявки и връщане на кеширани отговори за идентични заявки в рамките на времеви прозорец. |
|
||||
| `systemPrompt.ts` | Инжектиране на глобална системна подкана: добавя пред или добавя конфигурируема системна подкана към всички заявки, с обработка на съвместимостта за всеки доставчик. |
|
||||
| `thinkingBudget.ts` | Управление на бюджета на токените за разсъждение: поддържа режими за преминаване, автоматичен (конфигурация на лентово мислене), персонализиран (фиксиран бюджет) и адаптивен (мащабиран според сложността) режими за контролиране на токени за мислене/разсъждение. |
|
||||
| `wildcardRouter.ts` | Маршрутизиране на модела със заместващи знаци: разрешава шаблони със заместващи знаци (напр. `*/claude-*`) до конкретни двойки доставчик/модел въз основа на наличност и приоритет. |
|
||||
| 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, iFlow, 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
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
@@ -300,7 +304,7 @@ sequenceDiagram
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### Резервна държавна машина на акаунта
|
||||
#### Account Fallback State Machine
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
@@ -325,7 +329,7 @@ stateDiagram-v2
|
||||
}
|
||||
```
|
||||
|
||||
#### Комбиниран модел верига
|
||||
#### Combo Model Chain
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -344,11 +348,11 @@ flowchart LR
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Преводач (`open-sse/translator/`)
|
||||
### 4.5 Translator (`open-sse/translator/`)
|
||||
|
||||
**Машината за превод на формати**, използваща саморегистрираща се плъгин система.
|
||||
The **format translation engine** using a self-registering plugin system.
|
||||
|
||||
#### Архитектура
|
||||
#### Architecture
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
@@ -374,15 +378,15 @@ graph TD
|
||||
end
|
||||
```
|
||||
|
||||
| Указател | Файлове | Описание |
|
||||
| ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `request/` | 8 преводачи | Преобразувайте тела на заявки между формати. Всеки файл се саморегистрира чрез `register(from, to, fn)` при импортиране. |
|
||||
| `response/` | 7 преводачи | Преобразувайте поточно предавани отговори между формати. Обработва SSE типове събития, мисловни блокове, извиквания на инструменти. |
|
||||
| `helpers/` | 6 помощника | Споделени помощни програми: `claudeHelper` (извличане на системни подкани, мислеща конфигурация), `geminiHelper` (съпоставяне на части/съдържание), `openaiHelper` (филтриране на формат), `toolCallHelper` (генериране на ID, инжектиране на липсващ отговор), `maxTokensHelper`, `responsesApiHelper`. |
|
||||
| `index.ts` | — | Механизъм за превод: `translateRequest()`, `translateResponse()`, управление на състоянието, регистър. |
|
||||
| `formats.ts` | — | Константи на формата: `OPENAI`, `CLAUDE`, `GEMINI`, `ANTIGRAVITY`, `KIRO`, `CURSOR`, `OPENAI_RESPONSES`. |
|
||||
| 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
|
||||
// Each translator file calls register() on import:
|
||||
@@ -395,17 +399,17 @@ import "./request/claude-to-openai.js"; // ← self-registers
|
||||
|
||||
---
|
||||
|
||||
### 4.6 Помощни средства (`open-sse/utils/`)
|
||||
### 4.6 Utils (`open-sse/utils/`)
|
||||
|
||||
| Файл | Цел |
|
||||
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `error.ts` | Изграждане на отговор при грешка (съвместим с OpenAI формат), анализиране на грешка нагоре по веригата, извличане на времето за повторен опит на Antigravity от съобщения за грешка, поточно предаване на грешка на SSE. |
|
||||
| `stream.ts` | **SSE Transform Stream** — основният тръбопровод за стрийминг. Два режима: `TRANSLATE` (превод в пълен формат) и `PASSTHROUGH` (нормализиране + извличане на използването). Управлява буфериране на парчета, оценка на използването, проследяване на дължината на съдържанието. Екземплярите на енкодер/декодер на поток избягват споделено състояние. |
|
||||
| `streamHelpers.ts` | Помощни програми за SSE на ниско ниво: `parseSSELine` (толерантни към бели интервали), `hasValuableContent` (филтрира празни парчета за OpenAI/Claude/Gemini), `fixInvalidId`, `formatSSE` (сериализация на SSE, съобразена с формата с `perf_metrics` почистване). |
|
||||
| `usageTracking.ts` | Извличане на използване на токени от всеки формат (Claude/OpenAI/Gemini/Responses), оценка с отделни съотношения на инструмент/съобщение char-per-token, добавяне на буфер (марж за безопасност от 2000 токена), филтриране на специфично за формат поле, конзолно регистриране с ANSI цветове. |
|
||||
| `requestLogger.ts` | Регистриране на искания на базата на файл (включване чрез `ENABLE_REQUEST_LOGS=true`). Създава сесийни папки с номерирани файлове: `1_req_client.json` → `7_res_client.txt`. Всички I/O са асинхронни (задействай и забрави). Маскира чувствителните заглавки. |
|
||||
| `bypassHandler.ts` | Прихваща специфични модели от Claude CLI (извличане на заглавие, загряване, броене) и връща фалшиви отговори, без да се обажда на доставчик. Поддържа както стрийминг, така и не стрийминг. Умишлено ограничен до Claude CLI обхват. |
|
||||
| `networkProxy.ts` | Разрешава URL адрес на изходящ прокси за даден доставчик с приоритет: специфична за доставчика конфигурация → глобална конфигурация → променливи на средата (`HTTPS_PROXY`/`HTTP_PROXY`/`ALL_PROXY`). Поддържа `NO_PROXY` изключения. Кешира конфигурацията за 30s. |
|
||||
| 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
|
||||
|
||||
@@ -429,7 +433,7 @@ flowchart TD
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### Структура на сесията на регистратора на заявка
|
||||
#### Request Logger Session Structure
|
||||
|
||||
```
|
||||
logs/
|
||||
@@ -447,109 +451,109 @@ logs/
|
||||
|
||||
---
|
||||
|
||||
### 4.7 Приложен слой (`src/`)
|
||||
### 4.7 Application Layer (`src/`)
|
||||
|
||||
| Указател | Цел |
|
||||
| ------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| `src/app/` | Уеб потребителски интерфейс, API маршрути, Express междинен софтуер, манипулатори за обратно извикване OAuth |
|
||||
| `src/lib/` | Достъп до база данни (`localDb.ts`, `usageDb.ts`), удостоверяване, споделено |
|
||||
| `src/mitm/` | Прокси помощни програми Man-in-the-middle за прихващане на трафик на доставчик |
|
||||
| `src/models/` | Дефиниции на модел на база данни |
|
||||
| `src/shared/` | Обвивки около open-sse функции (доставчик, поток, грешка и др.) |
|
||||
| `src/sse/` | SSE манипулатори на крайни точки, които свързват библиотеката open-sse към експресни маршрути |
|
||||
| `src/store/` | Управление на състоянието на приложението |
|
||||
| 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 |
|
||||
|
||||
#### Известни API маршрути
|
||||
#### Notable API Routes
|
||||
|
||||
| Маршрут | Методи | Цел |
|
||||
| --------------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------- |
|
||||
| `/api/provider-models` | ПОЛУЧАВАНЕ/ПУБЛИКУВАНЕ/ИЗТРИВАНЕ | CRUD за потребителски модели на доставчик |
|
||||
| `/api/models/catalog` | ВЗЕМЕТЕ | Обобщен каталог на всички модели (чат, вграждане, изображение, персонализирани), групирани по доставчик |
|
||||
| `/api/settings/proxy` | ПОЛУЧАВАНЕ/ПОСТАВЯНЕ/ИЗТРИВАНЕ | Конфигурация на йерархичен изходящ прокси (`global/providers/combos/keys`) |
|
||||
| `/api/settings/proxy/test` | ПУБЛИКАЦИЯ | Потвърждава прокси свързаността и връща публичен IP/латентност |
|
||||
| `/v1/providers/[provider]/chat/completions` | ПУБЛИКАЦИЯ | Специализирани завършвания на чат за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[provider]/embeddings` | ПУБЛИКАЦИЯ | Специализирани вграждания за всеки доставчик с валидиране на модел |
|
||||
| `/v1/providers/[provider]/images/generations` | ПУБЛИКАЦИЯ | Специално генериране на изображения за всеки доставчик с валидиране на модел |
|
||||
| `/api/settings/ip-filter` | ВЗЕМИ/ПОСТАВИ | Управление на списък с разрешени/блокирани IP |
|
||||
| `/api/settings/thinking-budget` | ВЗЕМИ/ПОСТАВИ | Конфигурация на бюджета на токена за разсъждение (пропускане/автоматично/персонализирано/адаптивно) |
|
||||
| `/api/settings/system-prompt` | ВЗЕМИ/ПОСТАВИ | Бързо инжектиране на глобална система за всички заявки |
|
||||
| `/api/sessions` | ВЗЕМЕТЕ | Проследяване на активна сесия и показатели |
|
||||
| `/api/rate-limits` | ВЗЕМЕТЕ | Състояние на ограничение на лимита по сметка |
|
||||
| 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. Ключови модели на дизайн
|
||||
## 5. Key Design Patterns
|
||||
|
||||
### 5.1 Hub-and-Spoke превод
|
||||
### 5.1 Hub-and-Spoke Translation
|
||||
|
||||
Всички формати се превеждат през **OpenAI формат като център**. Добавянето на нов доставчик изисква само писане на **една двойка** преводачи (към/от OpenAI), а не на N двойки.
|
||||
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.
|
||||
|
||||
### 5.2 Модел на стратегия за изпълнител
|
||||
### 5.2 Executor Strategy Pattern
|
||||
|
||||
Всеки доставчик има специален клас изпълнител, наследен от `BaseExecutor`. Фабриката в `executors/index.ts` избира правилния по време на изпълнение.
|
||||
Each provider has a dedicated executor class inheriting from `BaseExecutor`. The factory in `executors/index.ts` selects the right one at runtime.
|
||||
|
||||
### 5.3 Саморегистрираща се плъгин система
|
||||
### 5.3 Self-Registering Plugin System
|
||||
|
||||
Модулите за преводач се регистрират при импортиране чрез `register()`. Добавянето на нов преводач е просто създаване на файл и импортирането му.
|
||||
Translator modules register themselves on import via `register()`. Adding a new translator is just creating a file and importing it.
|
||||
|
||||
### 5.4 Резервен акаунт с експоненциално отстъпление
|
||||
### 5.4 Account Fallback with Exponential Backoff
|
||||
|
||||
Когато доставчикът върне 429/401/500, системата може да превключи към следващия акаунт, прилагайки експоненциално охлаждане (1s → 2s → 4s → max 2min).
|
||||
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
|
||||
### 5.5 Combo Model Chains
|
||||
|
||||
„Комбо“ групира множество низове `provider/model`. Ако първият не успее, автоматично се върнете към следващия.
|
||||
A "combo" groups multiple `provider/model` strings. If the first fails, fallback to the next automatically.
|
||||
|
||||
### 5.6 Поточен превод с пълно състояние
|
||||
### 5.6 Stateful Streaming Translation
|
||||
|
||||
Преводът на отговор поддържа състоянието в SSE блокове (проследяване на мислещ блок, натрупване на извикване на инструмент, индексиране на блок съдържание) чрез механизма `initState()`.
|
||||
Response translation maintains state across SSE chunks (thinking block tracking, tool call accumulation, content block indexing) via the `initState()` mechanism.
|
||||
|
||||
### 5.7 Буфер за безопасност при използване
|
||||
### 5.7 Usage Safety Buffer
|
||||
|
||||
Добавя се буфер от 2000 токена към отчетеното използване, за да се предотврати достигането на ограниченията на контекстните прозорци на клиентите поради натоварване от системни подкани и превод на формати.
|
||||
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. Поддържани формати
|
||||
## 6. Supported Formats
|
||||
|
||||
| Формат | Посока | Идентификатор |
|
||||
| ------------------------- | -------------- | ------------------ |
|
||||
| Завършвания на OpenAI чат | източник + цел | `openai` |
|
||||
| OpenAI Responses API | източник + цел | `openai-responses` |
|
||||
| Антропичен Клод | източник + цел | `claude` |
|
||||
| Google Gemini | източник + цел | `gemini` |
|
||||
| Google Gemini CLI | само цел | `gemini-cli` |
|
||||
| Антигравитация | източник + цел | `antigravity` |
|
||||
| AWS Киро | само цел | `kiro` |
|
||||
| Курсор | само цел | `cursor` |
|
||||
| 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` |
|
||||
|
||||
---
|
||||
|
||||
## 7. Поддържани доставчици
|
||||
## 7. Supported Providers
|
||||
|
||||
| Доставчик | Метод за удостоверяване | Изпълнител | Основни бележки |
|
||||
| ------------------------ | -------------------------------- | --------------- | -------------------------------------------------- |
|
||||
| Антропичен Клод | API ключ или OAuth | По подразбиране | Използва `x-api-key` заглавка |
|
||||
| Google Gemini | API ключ или OAuth | По подразбиране | Използва `x-goog-api-key` заглавка |
|
||||
| Google Gemini CLI | OAuth | GeminiCLI | Използва `streamGenerateContent` крайна точка |
|
||||
| Антигравитация | OAuth | Антигравитация | Multi-URL резервен, персонализиран повторен анализ |
|
||||
| OpenAI | API ключ | По подразбиране | Удостоверяване на стандартен носител |
|
||||
| Кодекс | OAuth | Кодекс | Инжектира системни инструкции, управлява мисленето |
|
||||
| Копилот на GitHub | OAuth + Copilot token | Github | Двоен токен, имитираща заглавка на VSCode |
|
||||
| Киро (AWS) | AWS SSO OIDC или социални | Киро | Парсинг на двоичен EventStream |
|
||||
| Курсор IDE | Контролна сума за удостоверяване | Курсор | Protobuf кодиране, SHA-256 контролни суми |
|
||||
| Куен | OAuth | По подразбиране | Стандартно удостоверяване |
|
||||
| iFlow | OAuth (основен + носител) | По подразбиране | Заглавка за двойно удостоверяване |
|
||||
| OpenRouter | API ключ | По подразбиране | Удостоверяване на стандартен носител |
|
||||
| GLM, Kimi, MiniMax | API ключ | По подразбиране | Съвместим с Claude, използвайте `x-api-key` |
|
||||
| `openai-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с OpenAI |
|
||||
| `anthropic-compatible-*` | API ключ | По подразбиране | Динамично: всяка крайна точка, съвместима с Claude |
|
||||
| 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 |
|
||||
| iFlow | 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. Резюме на потока от данни
|
||||
## 8. Data Flow Summary
|
||||
|
||||
### Заявка за поточно предаване
|
||||
### Streaming Request
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -566,7 +570,7 @@ flowchart LR
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### Заявка без поточно предаване
|
||||
### Non-Streaming Request
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
@@ -577,7 +581,7 @@ flowchart LR
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### Байпасен поток (Claude CLI)
|
||||
### Bypass Flow (Claude CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
|
||||
@@ -1,77 +1,147 @@
|
||||
# OmniRoute — Галерия с функции на таблото
|
||||
# OmniRoute — Dashboard Features Gallery (Български)
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../FEATURES.md) | 🇧🇷 [Português (Brasil)](../pt-BR/FEATURES.md) | 🇪🇸 [Español](../es/FEATURES.md) | 🇫🇷 [Français](../fr/FEATURES.md) | 🇮🇹 [Italiano](../it/FEATURES.md) | 🇷🇺 [Русский](../ru/FEATURES.md) | 🇨🇳 [中文 (简体)](../zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](../de/FEATURES.md) | 🇮🇳 [हिन्दी](../in/FEATURES.md) | 🇹🇭 [ไทย](../th/FEATURES.md) | 🇺🇦 [Українська](../uk-UA/FEATURES.md) | 🇸🇦 [العربية](../ar/FEATURES.md) | 🇯🇵 [日本語](../ja/FEATURES.md) | 🇻🇳 [Tiếng Việt](../vi/FEATURES.md) | 🇧🇬 [Български](../bg/FEATURES.md) | 🇩🇰 [Dansk](../da/FEATURES.md) | 🇫🇮 [Suomi](../fi/FEATURES.md) | 🇮🇱 [עברית](../he/FEATURES.md) | 🇭🇺 [Magyar](../hu/FEATURES.md) | 🇮🇩 [Bahasa Indonesia](../id/FEATURES.md) | 🇰🇷 [한국어](../ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](../ms/FEATURES.md) | 🇳🇱 [Nederlands](../nl/FEATURES.md) | 🇳🇴 [Norsk](../no/FEATURES.md) | 🇵🇹 [Português (Portugal)](../pt/FEATURES.md) | 🇷🇴 [Română](../ro/FEATURES.md) | 🇵🇱 [Polski](../pl/FEATURES.md) | 🇸🇰 [Slovenčina](../sk/FEATURES.md) | 🇸🇪 [Svenska](../sv/FEATURES.md) | 🇵🇭 [Filipino](../phi/FEATURES.md)
|
||||
🌐 **Languages:** 🇺🇸 [English](../../../README.md) · 🇧🇷 [pt-BR](../pt-BR/README.md) · 🇪🇸 [es](../es/README.md) · 🇫🇷 [fr](../fr/README.md) · 🇩🇪 [de](../de/README.md) · 🇮🇹 [it](../it/README.md) · 🇷🇺 [ru](../ru/README.md) · 🇨🇳 [zh-CN](../zh-CN/README.md) · 🇯🇵 [ja](../ja/README.md) · 🇰🇷 [ko](../ko/README.md) · 🇸🇦 [ar](../ar/README.md) · 🇮🇳 [in](../in/README.md) · 🇹🇭 [th](../th/README.md) · 🇻🇳 [vi](../vi/README.md) · 🇮🇩 [id](../id/README.md) · 🇲🇾 [ms](../ms/README.md) · 🇳🇱 [nl](../nl/README.md) · 🇵🇱 [pl](../pl/README.md) · 🇸🇪 [sv](../sv/README.md) · 🇳🇴 [no](../no/README.md) · 🇩🇰 [da](../da/README.md) · 🇫🇮 [fi](../fi/README.md) · 🇵🇹 [pt](../pt/README.md) · 🇷🇴 [ro](../ro/README.md) · 🇭🇺 [hu](../hu/README.md) · 🇧🇬 [bg](../bg/README.md) · 🇸🇰 [sk](../sk/README.md) · 🇺🇦 [uk-UA](../uk-UA/README.md) · 🇮🇱 [he](../he/README.md) · 🇵🇭 [phi](../phi/README.md)
|
||||
|
||||
Визуално ръководство за всеки раздел на таблото за управление OmniRoute.
|
||||
> 🇺🇸 [English](../../../docs/FEATURES.md)
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Доставчици
|
||||
Visual guide to every section of the OmniRoute dashboard.
|
||||
|
||||
Управлявайте връзките на доставчици на AI: OAuth доставчици (Claude Code, Codex, Gemini CLI), доставчици на API ключове (Groq, DeepSeek, OpenRouter) и безплатни доставчици (iFlow, Qwen, Kiro).
|
||||
---
|
||||
|
||||
## 🔌 Providers
|
||||
|
||||
Manage AI provider connections: OAuth providers (Claude Code, Codex, Gemini CLI), API key providers (Groq, DeepSeek, OpenRouter), and free providers (iFlow, Qwen, Kiro). Kiro accounts include credit balance tracking — remaining credits, total allowance, and renewal date visible in Dashboard → Usage.
|
||||
|
||||

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

|
||||
|
||||
---
|
||||
|
||||
## 📊 Анализ
|
||||
## 📊 Analytics
|
||||
|
||||
Изчерпателни анализи на използването с потребление на токени, оценки на разходите, топлинни карти на активността, седмични диаграми на разпределение и разбивки по доставчик.
|
||||
Comprehensive usage analytics with token consumption, cost estimates, activity heatmaps, weekly distribution charts, and per-provider breakdowns.
|
||||
|
||||

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

|
||||
|
||||
---
|
||||
|
||||
## 🔧 Площадка за преводачи
|
||||
## 🔧 Translator Playground
|
||||
|
||||
Четири режима за отстраняване на грешки в API преводи: **Playground** (конвертор на формати), **Chat Tester** (заявки на живо), **Test Bench** (пакетни тестове) и **Live Monitor** (поток в реално време).
|
||||
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+)_
|
||||
|
||||
Общи настройки, системно съхранение, управление на архивиране (база данни за експортиране/импортиране), външен вид (тъмен/светъл режим), сигурност (включва защита на крайна точка на API и блокиране на потребителски доставчик), маршрутизиране, устойчивост и разширена конфигурация.
|
||||
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+)_
|
||||
|
||||
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
|
||||
- **Security** — API endpoint protection, custom provider blocking, IP filtering, session info
|
||||
- **Routing** — Model aliases, background task degradation
|
||||
- **Resilience** — Rate limit persistence, circuit breaker tuning
|
||||
- **Advanced** — Configuration overrides
|
||||
|
||||

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

|
||||
|
||||
---
|
||||
|
||||
## 📝 Регистри за заявки
|
||||
## 🤖 CLI Agents _(v2.0.11+)_
|
||||
|
||||
Регистриране на заявки в реално време с филтриране по доставчик, модел, акаунт и API ключ. Показва кодове за състояние, използване на токени, латентност и подробности за отговора.
|
||||
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:
|
||||
|
||||
- **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
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ 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
|
||||
## 🌐 API Endpoint
|
||||
|
||||
Вашата унифицирана крайна точка на API с разбивка на възможностите: завършвания на чат, вграждания, генериране на изображения, прекласиране, аудио транскрипция и регистрирани ключове за API.
|
||||
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. Cloud proxy support for remote access.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔑 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.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Audit Log
|
||||
|
||||
Administrative action tracking with filtering by action type, actor, target, IP address, and timestamp. Full security event history.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ 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.
|
||||
|
||||
87
docs/i18n/bg/MCP-SERVER.md
Normal file
87
docs/i18n/bg/MCP-SERVER.md
Normal file
@@ -0,0 +1,87 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/MCP-SERVER.md) · 🇪🇸 [es](../es/MCP-SERVER.md) · 🇫🇷 [fr](../fr/MCP-SERVER.md) · 🇩🇪 [de](../de/MCP-SERVER.md) · 🇮🇹 [it](../it/MCP-SERVER.md) · 🇷🇺 [ru](../ru/MCP-SERVER.md) · 🇨🇳 [zh-CN](../zh-CN/MCP-SERVER.md) · 🇯🇵 [ja](../ja/MCP-SERVER.md) · 🇰🇷 [ko](../ko/MCP-SERVER.md) · 🇸🇦 [ar](../ar/MCP-SERVER.md) · 🇮🇳 [in](../in/MCP-SERVER.md) · 🇹🇭 [th](../th/MCP-SERVER.md) · 🇻🇳 [vi](../vi/MCP-SERVER.md) · 🇮🇩 [id](../id/MCP-SERVER.md) · 🇲🇾 [ms](../ms/MCP-SERVER.md) · 🇳🇱 [nl](../nl/MCP-SERVER.md) · 🇵🇱 [pl](../pl/MCP-SERVER.md) · 🇸🇪 [sv](../sv/MCP-SERVER.md) · 🇳🇴 [no](../no/MCP-SERVER.md) · 🇩🇰 [da](../da/MCP-SERVER.md) · 🇫🇮 [fi](../fi/MCP-SERVER.md) · 🇵🇹 [pt](../pt/MCP-SERVER.md) · 🇷🇴 [ro](../ro/MCP-SERVER.md) · 🇭🇺 [hu](../hu/MCP-SERVER.md) · 🇧🇬 [bg](../bg/MCP-SERVER.md) · 🇸🇰 [sk](../sk/MCP-SERVER.md) · 🇺🇦 [uk-UA](../uk-UA/MCP-SERVER.md) · 🇮🇱 [he](../he/MCP-SERVER.md) · 🇵🇭 [phi](../phi/MCP-SERVER.md)
|
||||
|
||||
---
|
||||
|
||||
# OmniRoute MCP Server Documentation
|
||||
|
||||
> Model Context Protocol server with 16 intelligent tools
|
||||
|
||||
## Installation
|
||||
|
||||
OmniRoute MCP is built-in. Start it with:
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Or via the open-sse transport:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
```
|
||||
|
||||
## IDE Configuration
|
||||
|
||||
See [IDE Configs](integrations/ide-configs.md) for Antigravity, Cursor, Copilot, and Claude Desktop setup.
|
||||
|
||||
---
|
||||
|
||||
## 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 |
|
||||
|
||||
## 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 |
|
||||
| `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 |
|
||||
|
||||
## Authentication
|
||||
|
||||
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 |
|
||||
|
||||
## 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 |
|
||||
@@ -8,6 +8,16 @@ _Вашият универсален API прокси — една крайна
|
||||
|
||||
---
|
||||
|
||||
### 🆕 What's New in v2.7.0
|
||||
|
||||
- **Pluggable RouterStrategy** — rules, cost, and latency routing strategies
|
||||
- **Multilingual intent detection** — routing scoring in 30+ languages
|
||||
- **Request deduplication** — prevent duplicate API calls via content hash
|
||||
- **New providers:** Grok-4 Fast (xAI), GLM-5 / Z.AI, MiniMax M2.5, Kimi K2.5
|
||||
- **Updated pricing:** Grok-4 Fast $0.20/$0.50/M, GLM-5 $0.50/M, MiniMax M2.5 $0.30/M
|
||||
|
||||
---
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](https://www.npmjs.com/package/omniroute)
|
||||
@@ -20,7 +30,7 @@ _Вашият универсален API прокси — една крайна
|
||||
|
||||
</div>
|
||||
|
||||
🌐 **Налично на:** 🇺🇸 [английски](README.md) | 🇧🇷 [Португалски (Бразилия)](README.pt-BR.md) | 🇪🇸 [Испански] (README.es.md) | 🇫🇷 [Français](README.fr.md) | 🇮🇹 [италиански] (README.it.md) | 🇷🇺 [Русский](README.ru.md) | 🇨🇳 [中文 (简体)](README.zh-CN.md) | 🇩🇪 [Deutsch](README.de.md) | 🇮🇳 [हिन्दी] (README.in.md) | 🇹🇭 [ไทย](README.th.md) | 🇺🇦 [Українська](README.uk-UA.md) | 🇸🇦 [العربية](README.ar.md) | 🇯🇵 [日本語](README.ja.md) | 🇻🇳 [Tiếng Việt](README.vi.md) | 🇧🇬 [Български](README.bg.md) | 🇩🇰 [Dansk](README.da.md) | 🇫🇮 [Suomi](README.fi.md) | 🇮🇱 [עברית](README.he.md) | 🇭🇺 [маджарски] (README.hu.md) | 🇮🇩 [бахаса Индонезия](README.id.md) | 🇰🇷 [한국어](README.ko.md) | 🇲🇾 [Bahasa Melayu](README.ms.md) | 🇳🇱 [Нидерландия](README.nl.md) | 🇳🇴 [Norsk](README.no.md) | 🇵🇹 [Português (Португалия)](README.pt.md) | 🇷🇴 [Română](README.ro.md) | 🇵🇱 [Полски](README.pl.md) | 🇸🇰 [Slovenčina](README.sk.md) | 🇸🇪 [Svenska](README.sv.md) | 🇵🇭 [филипински] (README.phi.md)
|
||||
🌐 **Налично на:** 🇺🇸 [английски](../../README.md) | 🇧🇷 [Португалски (Бразилия)](../pt-BR/README.md) | 🇪🇸 [Испански] (../es/README.md) | 🇫🇷 [Français](../fr/README.md) | 🇮🇹 [италиански] (../it/README.md) | 🇷🇺 [Русский](../ru/README.md) | 🇨🇳 [中文 (简体)](../zh-CN/README.md) | 🇩🇪 [Deutsch](../de/README.md) | 🇮🇳 [हिन्दी] (../in/README.md) | 🇹🇭 [ไทย](../th/README.md) | 🇺🇦 [Українська](../uk-UA/README.md) | 🇸🇦 [العربية](../ar/README.md) | 🇯🇵 [日本語](../ja/README.md) | 🇻🇳 [Tiếng Việt](../vi/README.md) | 🇧🇬 [Български](../bg/README.md) | 🇩🇰 [Dansk](../da/README.md) | 🇫🇮 [Suomi](../fi/README.md) | 🇮🇱 [עברית](../he/README.md) | 🇭🇺 [маджарски] (../hu/README.md) | 🇮🇩 [бахаса Индонезия](../id/README.md) | 🇰🇷 [한국어](../ko/README.md) | 🇲🇾 [Bahasa Melayu](../ms/README.md) | 🇳🇱 [Нидерландия](../nl/README.md) | 🇳🇴 [Norsk](../no/README.md) | 🇵🇹 [Português (Португалия)](../pt/README.md) | 🇷🇴 [Română](../ro/README.md) | 🇵🇱 [Полски](../pl/README.md) | 🇸🇰 [Slovenčina](../sk/README.md) | 🇸🇪 [Svenska](../sv/README.md) | 🇵🇭 [филипински] (../phi/README.md)
|
||||
|
||||
---
|
||||
|
||||
@@ -53,6 +63,18 @@ _Вашият универсален API прокси — една крайна
|
||||
|
||||
---
|
||||
|
||||
### 🚀 New in v2.0.9+ — Playground, CLI Fingerprints & ACP
|
||||
|
||||
| Feature | What It Does |
|
||||
| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 🎮 **Model Playground** | Dashboard page to test any model directly — provider/model/endpoint selectors, Monaco Editor, streaming, abort, timing |
|
||||
| 🔏 **CLI Fingerprint Matching** | Per-provider header/body ordering to match native CLI signatures — toggle per provider in Settings > Security. **Your proxy IP is preserved** |
|
||||
| 🤝 **ACP Support (Agent Client Protocol)** | CLI agent discovery (Codex, Claude, Goose, Gemini CLI, OpenClaw), process spawner, `/api/acp/agents` endpoint |
|
||||
| 🤖 **ACP Agents Dashboard** | Debug > Agents page — grid of 14 agents with install status, version, custom agent form for any CLI tool |
|
||||
| 🔧 **Custom Model `apiFormat` Routing** | Custom models with `apiFormat: "responses"` now correctly route to the Responses API translator |
|
||||
| 🏢 **Codex Workspace Isolation** | Multiple Codex workspaces per email — OAuth correctly separates connections by workspace ID |
|
||||
| 🔄 **Electron Auto-Update** | Desktop app checks for updates + auto-install on restart |
|
||||
|
||||
### 🤖 Безплатен доставчик на AI за вашите любими кодиращи агенти
|
||||
|
||||
_Свържете всеки базиран на AI IDE или CLI инструмент чрез OmniRoute — безплатен API шлюз за неограничено кодиране._
|
||||
@@ -253,6 +275,7 @@ OpenAI използва един формат, Claude (Anthropic) използв
|
||||
**Как OmniRoute го решава:**
|
||||
|
||||
- **Вградени доставчици на безплатни нива** — Вградена поддръжка за 100% безплатни доставчици: iFlow (8 неограничени модела), Qwen (3 неограничени модела), Kiro (Claude безплатно), Gemini CLI (180K/месец безплатно)
|
||||
- **Ollama Cloud** — Cloud-hosted Ollama models at `api.ollama.com` with free "Light usage" tier; use `ollamacloud/<model>` prefix
|
||||
- **Безплатни само комбинации** — Верига `gc/gemini-3-flash → if/kimi-k2-thinking → qw/qwen3-coder-plus` = $0/месец с нулев престой
|
||||
- **NVIDIA NIM безплатни кредити** — интегрирани 1000 безплатни кредита
|
||||
- **Стратегия за оптимизиране на разходите** — Стратегия за маршрутизиране, която автоматично избира най-евтиния наличен доставчик
|
||||
@@ -393,7 +416,7 @@ AI не е просто завършване на чат. Разработчиц
|
||||
- **Текст към видео** — `/v1/videos/generations` — ComfyUI (AnimateDiff, SVD) и SD WebUI
|
||||
- **Текст към музика** — `/v1/music/generations` — ComfyUI (Stable Audio Open, MusicGen)
|
||||
- **Аудио транскрипция** — `/v1/audio/transcriptions` — Whisper + Nvidia NIM, HuggingFace, Qwen3
|
||||
- **Текст-към-говор** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, + съществуващи доставчици
|
||||
- **Текст-към-говор** — `/v1/audio/speech` — ElevenLabs, Nvidia NIM, HuggingFace, Coqui, Tortoise, Qwen3, Inworld, Cartesia, PlayHT, + съществуващи доставчици
|
||||
- **Модерации** — `/v1/moderations` — Проверки за безопасност на съдържанието
|
||||
- **Прекласиране** — `/v1/rerank` — Прекласиране на уместността на документа
|
||||
- **API за отговори** — Пълна `/v1/responses` поддръжка за Codex
|
||||
@@ -910,8 +933,8 @@ OmniRoute v2.0 е създаден като операционна платфо
|
||||
| Характеристика | Какво прави || -------------------------- | ------------------------------------------------------------ |
|
||||
| 🖼️ **Генериране на изображения** | `/v1/images/generations` с облак и локален бекенд |
|
||||
| 📐 **Вграждания** | `/v1/embeddings` за търсене и RAG тръбопроводи |
|
||||
| 🎤 **Аудио транскрипция** | `/v1/audio/transcriptions` (Whisper и допълнителни доставчици) |
|
||||
| 🔊 **Текст към говор** | `/v1/audio/speech` (множество машини/доставчици) |
|
||||
| 🎤 **Аудио транскрипция** | `/v1/audio/transcriptions` — 7 providers (Deepgram Nova 3, AssemblyAI, Groq Whisper, HuggingFace, ElevenLabs, OpenAI, Azure), auto-language detection, MP4/MP3/WAV support |
|
||||
| 🔊 **Текст към говор** | `/v1/audio/speech` — 10 providers (ElevenLabs, OpenAI, Deepgram, Cartesia, PlayHT, HuggingFace, Nvidia NIM, Inworld, Coqui, Tortoise) |
|
||||
| 🎬 **Видео генериране** | `/v1/videos/generations` (работни процеси ComfyUI + SD WebUI) |
|
||||
| 🎵 **Музикално поколение** | `/v1/music/generations` (работни процеси на ComfyUI) |
|
||||
| 🛡️ **Модерации** | `/v1/moderations` проверки за безопасност |
|
||||
@@ -919,17 +942,18 @@ OmniRoute v2.0 е създаден като операционна платфо
|
||||
|
||||
### 🛡️ Устойчивост, сигурност и управление
|
||||
|
||||
| Характеристика | Какво прави |
|
||||
| -------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| 🔌 **Прекъсвачи** | Пътуване/възстановяване на ниво доставчик с прагови контроли |
|
||||
| 🛡️ **Anti-Thundering Herd** | Защита на Mutex + семафор при събития за повторен опит/скорост |
|
||||
| 🧠 **Семантичен + кеш на подписа** | Намаляване на разходите/закъснението с два кеш слоя |
|
||||
| ⚡ **Искане на идемпотентност** | Дублиран защитен прозорец |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | По-добра съвместимост с доставчици, филтрирани срещу бот |
|
||||
| 🌐 **IP филтриране** | Списък с разрешени/списъци с блокирани контроли за открити внедрявания |
|
||||
| 📊 **Редактируеми ограничения на скоростта** | Конфигурируеми глобални/на ниво доставчик ограничения с постоянство |
|
||||
| 🔑 **API Key Management + Scoping** | Сигурно издаване/ротация на ключове и контроли на модел/доставчик |
|
||||
| 🛡️ **Защитен `/models`** | Опционално удостоверяване и скриване на доставчик за каталог на модели |
|
||||
| Характеристика | Какво прави |
|
||||
| -------------------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| 🔌 **Прекъсвачи** | Пътуване/възстановяване на ниво доставчик с прагови контроли |
|
||||
| 🛡️ **Anti-Thundering Herd** | Защита на Mutex + семафор при събития за повторен опит/скорост |
|
||||
| 🧠 **Семантичен + кеш на подписа** | Намаляване на разходите/закъснението с два кеш слоя |
|
||||
| ⚡ **Искане на идемпотентност** | Дублиран защитен прозорец |
|
||||
| 🔒 **TLS Fingerprint Spoofing** | По-добра съвместимост с доставчици, филтрирани срещу бот |
|
||||
| 🔏 **CLI Fingerprint Matching** | Matches native CLI request signatures — **reduces ban risk while preserving proxy IP** |
|
||||
| 🌐 **IP филтриране** | Списък с разрешени/списъци с блокирани контроли за открити внедрявания |
|
||||
| 📊 **Редактируеми ограничения на скоростта** | Конфигурируеми глобални/на ниво доставчик ограничения с постоянство |
|
||||
| 🔑 **API Key Management + Scoping** | Сигурно издаване/ротация на ключове и контроли на модел/доставчик |
|
||||
| 🛡️ **Защитен `/models`** | Опционално удостоверяване и скриване на доставчик за каталог на модели |
|
||||
|
||||
### 📊 Наблюдаемост и анализ
|
||||
|
||||
@@ -1645,15 +1669,9 @@ gh release create v2.0.0 --title "v2.0.0" --generate-notes
|
||||
|
||||
## 📊 Звездна история
|
||||
|
||||
<a href="https://star-history.com/#diegosouzapw/OmniRoute&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=diegosouzapw/OmniRoute&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
## Stargazers over time
|
||||
|
||||
---
|
||||
## [](https://starchart.cc/diegosouzapw/OmniRoute)
|
||||
|
||||
## 🙏 Благодарности
|
||||
|
||||
37
docs/i18n/bg/RELEASE_CHECKLIST.md
Normal file
37
docs/i18n/bg/RELEASE_CHECKLIST.md
Normal file
@@ -0,0 +1,37 @@
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/RELEASE_CHECKLIST.md) · 🇪🇸 [es](../es/RELEASE_CHECKLIST.md) · 🇫🇷 [fr](../fr/RELEASE_CHECKLIST.md) · 🇩🇪 [de](../de/RELEASE_CHECKLIST.md) · 🇮🇹 [it](../it/RELEASE_CHECKLIST.md) · 🇷🇺 [ru](../ru/RELEASE_CHECKLIST.md) · 🇨🇳 [zh-CN](../zh-CN/RELEASE_CHECKLIST.md) · 🇯🇵 [ja](../ja/RELEASE_CHECKLIST.md) · 🇰🇷 [ko](../ko/RELEASE_CHECKLIST.md) · 🇸🇦 [ar](../ar/RELEASE_CHECKLIST.md) · 🇮🇳 [in](../in/RELEASE_CHECKLIST.md) · 🇹🇭 [th](../th/RELEASE_CHECKLIST.md) · 🇻🇳 [vi](../vi/RELEASE_CHECKLIST.md) · 🇮🇩 [id](../id/RELEASE_CHECKLIST.md) · 🇲🇾 [ms](../ms/RELEASE_CHECKLIST.md) · 🇳🇱 [nl](../nl/RELEASE_CHECKLIST.md) · 🇵🇱 [pl](../pl/RELEASE_CHECKLIST.md) · 🇸🇪 [sv](../sv/RELEASE_CHECKLIST.md) · 🇳🇴 [no](../no/RELEASE_CHECKLIST.md) · 🇩🇰 [da](../da/RELEASE_CHECKLIST.md) · 🇫🇮 [fi](../fi/RELEASE_CHECKLIST.md) · 🇵🇹 [pt](../pt/RELEASE_CHECKLIST.md) · 🇷🇴 [ro](../ro/RELEASE_CHECKLIST.md) · 🇭🇺 [hu](../hu/RELEASE_CHECKLIST.md) · 🇧🇬 [bg](../bg/RELEASE_CHECKLIST.md) · 🇸🇰 [sk](../sk/RELEASE_CHECKLIST.md) · 🇺🇦 [uk-UA](../uk-UA/RELEASE_CHECKLIST.md) · 🇮🇱 [he](../he/RELEASE_CHECKLIST.md) · 🇵🇭 [phi](../phi/RELEASE_CHECKLIST.md)
|
||||
|
||||
---
|
||||
|
||||
# Release Checklist
|
||||
|
||||
Use this checklist before tagging or publishing a new OmniRoute release.
|
||||
|
||||
## Version and Changelog
|
||||
|
||||
1. Bump `package.json` version (`x.y.z`) in the release branch.
|
||||
2. Move release notes from `## [Unreleased]` in `CHANGELOG.md` to a dated section:
|
||||
- `## [x.y.z] — YYYY-MM-DD`
|
||||
3. Keep `## [Unreleased]` as the first changelog section for upcoming work.
|
||||
4. Ensure the latest semver section in `CHANGELOG.md` equals `package.json` version.
|
||||
|
||||
## API Docs
|
||||
|
||||
1. Update `docs/openapi.yaml`:
|
||||
- `info.version` must equal `package.json` version.
|
||||
2. Validate endpoint examples if API contracts changed.
|
||||
|
||||
## 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).
|
||||
@@ -1,87 +1,91 @@
|
||||
# Отстраняване на неизправности
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](../pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](../es/TROUBLESHOOTING.md) | 🇫🇷 [Français](../fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](../it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](../ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](../zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](../de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](../in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](../th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](../uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](../ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](../ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](../vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](../bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](../da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](../fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](../he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](../hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](../id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](../ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](../ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](../nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](../no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](../pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](../ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](../pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](../sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](../sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
Често срещани проблеми и решения за OmniRoute.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/TROUBLESHOOTING.md) · 🇪🇸 [es](../es/TROUBLESHOOTING.md) · 🇫🇷 [fr](../fr/TROUBLESHOOTING.md) · 🇩🇪 [de](../de/TROUBLESHOOTING.md) · 🇮🇹 [it](../it/TROUBLESHOOTING.md) · 🇷🇺 [ru](../ru/TROUBLESHOOTING.md) · 🇨🇳 [zh-CN](../zh-CN/TROUBLESHOOTING.md) · 🇯🇵 [ja](../ja/TROUBLESHOOTING.md) · 🇰🇷 [ko](../ko/TROUBLESHOOTING.md) · 🇸🇦 [ar](../ar/TROUBLESHOOTING.md) · 🇮🇳 [in](../in/TROUBLESHOOTING.md) · 🇹🇭 [th](../th/TROUBLESHOOTING.md) · 🇻🇳 [vi](../vi/TROUBLESHOOTING.md) · 🇮🇩 [id](../id/TROUBLESHOOTING.md) · 🇲🇾 [ms](../ms/TROUBLESHOOTING.md) · 🇳🇱 [nl](../nl/TROUBLESHOOTING.md) · 🇵🇱 [pl](../pl/TROUBLESHOOTING.md) · 🇸🇪 [sv](../sv/TROUBLESHOOTING.md) · 🇳🇴 [no](../no/TROUBLESHOOTING.md) · 🇩🇰 [da](../da/TROUBLESHOOTING.md) · 🇫🇮 [fi](../fi/TROUBLESHOOTING.md) · 🇵🇹 [pt](../pt/TROUBLESHOOTING.md) · 🇷🇴 [ro](../ro/TROUBLESHOOTING.md) · 🇭🇺 [hu](../hu/TROUBLESHOOTING.md) · 🇧🇬 [bg](../bg/TROUBLESHOOTING.md) · 🇸🇰 [sk](../sk/TROUBLESHOOTING.md) · 🇺🇦 [uk-UA](../uk-UA/TROUBLESHOOTING.md) · 🇮🇱 [he](../he/TROUBLESHOOTING.md) · 🇵🇭 [phi](../phi/TROUBLESHOOTING.md)
|
||||
|
||||
---
|
||||
|
||||
## Бързи поправки
|
||||
# Troubleshooting
|
||||
|
||||
| Проблем | Решение |
|
||||
| ------------------------------------------------- | ------------------------------------------------------------------------------ |
|
||||
| Първото влизане не работи | Проверете `INITIAL_PASSWORD` в `.env` (по подразбиране: `123456`) |
|
||||
| Таблото се отваря на грешен порт | Задайте `PORT=20128` и `NEXT_PUBLIC_BASE_URL=http://localhost:20128` |
|
||||
| Няма регистрационни файлове за заявки под `logs/` | Задайте `ENABLE_REQUEST_LOGS=true` |
|
||||
| EACCES: разрешението е отказано | Задайте `DATA_DIR=/path/to/writable/dir` да замени `~/.omniroute` |
|
||||
| Стратегията за маршрутизиране не се запазва | Актуализация до v1.4.11+ (корекция на Zod схема за постоянство на настройките) |
|
||||
🌐 **Languages:** 🇺🇸 [English](TROUBLESHOOTING.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/TROUBLESHOOTING.md) | 🇪🇸 [Español](i18n/es/TROUBLESHOOTING.md) | 🇫🇷 [Français](i18n/fr/TROUBLESHOOTING.md) | 🇮🇹 [Italiano](i18n/it/TROUBLESHOOTING.md) | 🇷🇺 [Русский](i18n/ru/TROUBLESHOOTING.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/TROUBLESHOOTING.md) | 🇩🇪 [Deutsch](i18n/de/TROUBLESHOOTING.md) | 🇮🇳 [हिन्दी](i18n/in/TROUBLESHOOTING.md) | 🇹🇭 [ไทย](i18n/th/TROUBLESHOOTING.md) | 🇺🇦 [Українська](i18n/uk-UA/TROUBLESHOOTING.md) | 🇸🇦 [العربية](i18n/ar/TROUBLESHOOTING.md) | 🇯🇵 [日本語](i18n/ja/TROUBLESHOOTING.md) | 🇻🇳 [Tiếng Việt](i18n/vi/TROUBLESHOOTING.md) | 🇧🇬 [Български](i18n/bg/TROUBLESHOOTING.md) | 🇩🇰 [Dansk](i18n/da/TROUBLESHOOTING.md) | 🇫🇮 [Suomi](i18n/fi/TROUBLESHOOTING.md) | 🇮🇱 [עברית](i18n/he/TROUBLESHOOTING.md) | 🇭🇺 [Magyar](i18n/hu/TROUBLESHOOTING.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/TROUBLESHOOTING.md) | 🇰🇷 [한국어](i18n/ko/TROUBLESHOOTING.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/TROUBLESHOOTING.md) | 🇳🇱 [Nederlands](i18n/nl/TROUBLESHOOTING.md) | 🇳🇴 [Norsk](i18n/no/TROUBLESHOOTING.md) | 🇵🇹 [Português (Portugal)](i18n/pt/TROUBLESHOOTING.md) | 🇷🇴 [Română](i18n/ro/TROUBLESHOOTING.md) | 🇵🇱 [Polski](i18n/pl/TROUBLESHOOTING.md) | 🇸🇰 [Slovenčina](i18n/sk/TROUBLESHOOTING.md) | 🇸🇪 [Svenska](i18n/sv/TROUBLESHOOTING.md) | 🇵🇭 [Filipino](i18n/phi/TROUBLESHOOTING.md)
|
||||
|
||||
Common problems and solutions for OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с доставчика
|
||||
## Quick Fixes
|
||||
|
||||
### „Езиковият модел не предостави съобщения“
|
||||
|
||||
**Причина:** Квотата на доставчика е изчерпана.
|
||||
|
||||
**Коригиране:**
|
||||
|
||||
1. Проверете инструмента за проследяване на квоти на таблото за управление
|
||||
2. Използвайте комбо с резервни нива
|
||||
3. Преминете към по-евтино/безплатно ниво
|
||||
|
||||
### Ограничаване на скоростта
|
||||
|
||||
**Причина:** Абонаментната квота е изчерпана.
|
||||
|
||||
**Коригиране:**
|
||||
|
||||
- Добавете резервен вариант: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Използвайте GLM/MiniMax като евтино резервно копие
|
||||
|
||||
### OAuth Token е изтекъл
|
||||
|
||||
OmniRoute автоматично опреснява токените. Ако проблемите продължават:
|
||||
|
||||
1. Табло → Доставчик → Свързване отново
|
||||
2. Изтрийте и добавете отново връзката с доставчика
|
||||
| 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
|
||||
|
||||
### Грешки при синхронизиране в облак
|
||||
### "Language model did not provide messages"
|
||||
|
||||
1. Проверете дали `BASE_URL` сочи към вашия работещ екземпляр (напр. `http://localhost:20128`)
|
||||
2. Проверете `CLOUD_URL` точки към вашата крайна точка в облака (напр. `https://omniroute.dev`)
|
||||
3. Поддържайте стойностите на `NEXT_PUBLIC_*` в съответствие със стойностите от страна на сървъра
|
||||
**Cause:** Provider quota exhausted.
|
||||
|
||||
### Cloud `stream=false` Връща 500
|
||||
**Fix:**
|
||||
|
||||
**Симптом:** `Unexpected token 'd'...` в крайна точка на облака за обаждания без поточно предаване.
|
||||
1. Check dashboard quota tracker
|
||||
2. Use a combo with fallback tiers
|
||||
3. Switch to cheaper/free tier
|
||||
|
||||
**Причина:** Upstream връща SSE полезен товар, докато клиентът очаква JSON.
|
||||
### Rate Limiting
|
||||
|
||||
**Заобиколно решение:** Използвайте `stream=true` за директни обаждания в облака. Локалното време на изпълнение включва резервен SSE→JSON.
|
||||
**Cause:** Subscription quota exhausted.
|
||||
|
||||
### Облакът казва Свързан, но „Невалиден API ключ“
|
||||
**Fix:**
|
||||
|
||||
1. Създайте нов ключ от локалното табло за управление (`/api/keys`)
|
||||
2. Стартирайте облачна синхронизация: Активирайте Облак → Синхронизирай сега
|
||||
3. Старите/несинхронизирани ключове все още могат да връщат `401` в облака
|
||||
- Add fallback: `cc/claude-opus-4-6 → glm/glm-4.7 → if/kimi-k2-thinking`
|
||||
- Use GLM/MiniMax as cheap backup
|
||||
|
||||
### OAuth Token Expired
|
||||
|
||||
OmniRoute auto-refreshes tokens. If issues persist:
|
||||
|
||||
1. Dashboard → Provider → Reconnect
|
||||
2. Delete and re-add the provider connection
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с Docker
|
||||
## Cloud Issues
|
||||
|
||||
### CLI инструментът показва, че не е инсталиран
|
||||
### Cloud Sync Errors
|
||||
|
||||
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`: двоичен файл е намерен, но проверката на състоянието е неуспешна
|
||||
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
|
||||
|
||||
### Бързо валидиране по време на изпълнение
|
||||
### Cloud `stream=false` Returns 500
|
||||
|
||||
**Symptom:** `Unexpected token 'd'...` on cloud endpoint for non-streaming calls.
|
||||
|
||||
**Cause:** Upstream returns SSE payload while client expects JSON.
|
||||
|
||||
**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
|
||||
|
||||
### 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
|
||||
|
||||
### Quick Runtime Validation
|
||||
|
||||
```bash
|
||||
curl -s http://localhost:20128/api/cli-tools/codex-settings | jq '{installed,runnable,commandPath,runtimeMode,reason}'
|
||||
@@ -91,24 +95,24 @@ curl -s http://localhost:20128/api/cli-tools/openclaw-settings | jq '{installed,
|
||||
|
||||
---
|
||||
|
||||
## Проблеми с разходите
|
||||
## Cost Issues
|
||||
|
||||
### Високи разходи
|
||||
### High Costs
|
||||
|
||||
1. Проверете статистическите данни за употреба в Табло → Използване
|
||||
2. Превключете основния модел на GLM/MiniMax
|
||||
3. Използвайте безплатно ниво (Gemini CLI, iFlow) за некритични задачи
|
||||
4. Задайте бюджети за разходи за API ключ: Табло за управление → API ключове → Бюджет
|
||||
1. Check usage stats in Dashboard → Usage
|
||||
2. Switch primary model to GLM/MiniMax
|
||||
3. Use free tier (Gemini CLI, iFlow) for non-critical tasks
|
||||
4. Set cost budgets per API key: Dashboard → API Keys → Budget
|
||||
|
||||
---
|
||||
|
||||
## Отстраняване на грешки
|
||||
## Debugging
|
||||
|
||||
### Активиране на регистрационните файлове на заявките
|
||||
### Enable Request Logs
|
||||
|
||||
Задайте `ENABLE_REQUEST_LOGS=true` във вашия `.env` файл. Дневниците се появяват в директорията `logs/`.
|
||||
Set `ENABLE_REQUEST_LOGS=true` in your `.env` file. Logs appear under `logs/` directory.
|
||||
|
||||
### Проверете здравето на доставчика
|
||||
### Check Provider Health
|
||||
|
||||
```bash
|
||||
# Health dashboard
|
||||
@@ -118,102 +122,137 @@ http://localhost:20128/dashboard/health
|
||||
curl http://localhost:20128/api/monitoring/health
|
||||
```
|
||||
|
||||
### Съхранение по време на изпълнение
|
||||
### Runtime Storage
|
||||
|
||||
- Основно състояние: `${DATA_DIR}/db.json` (доставчици, комбинации, псевдоними, ключове, настройки)
|
||||
- Използване: `${DATA_DIR}/usage.json`, `${DATA_DIR}/log.txt`, `${DATA_DIR}/call_logs/`
|
||||
- Регистрации за заявки: `<repo>/logs/...` (когато `ENABLE_REQUEST_LOGS=true`)
|
||||
- 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
|
||||
|
||||
### Доставчикът остана в ОТВОРЕНО състояние
|
||||
### Provider stuck in OPEN state
|
||||
|
||||
Когато прекъсвачът на доставчика е ОТВОРЕЕН, заявките се блокират, докато изтече времето за охлаждане.
|
||||
When a provider's circuit breaker is OPEN, requests are blocked until the cooldown expires.
|
||||
|
||||
**Коригиране:**
|
||||
**Fix:**
|
||||
|
||||
1. Отидете на **Табло → Настройки → Устойчивост**
|
||||
2. Проверете картата на прекъсвача на засегнатия доставчик
|
||||
3. Щракнете върху **Нулиране на всички**, за да изчистите всички прекъсвачи, или изчакайте времето за охлаждане да изтече
|
||||
4. Уверете се, че доставчикът действително е наличен, преди да нулирате
|
||||
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
|
||||
|
||||
### Доставчикът продължава да изключва прекъсвача
|
||||
### Provider keeps tripping the circuit breaker
|
||||
|
||||
Ако доставчик многократно влиза в ОТВОРЕНО състояние:
|
||||
If a provider repeatedly enters OPEN state:
|
||||
|
||||
1. Проверете **Табло → Здраве → Здраве на доставчика** за модела на повреда
|
||||
2. Отидете на **Настройки → Устойчивост → Профили на доставчици** и увеличете прага на отказ
|
||||
3. Проверете дали доставчикът е променил ограниченията на API или изисква повторно удостоверяване
|
||||
4. Прегледайте телеметрията за латентност — високата латентност може да причини грешки, базирани на изчакване
|
||||
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
|
||||
|
||||
### Грешка „Неподдържан модел“.
|
||||
### "Unsupported model" error
|
||||
|
||||
- Уверете се, че използвате правилния префикс: `deepgram/nova-3` или `assemblyai/best`
|
||||
- Проверете дали доставчикът е свързан в **Табло → Доставчици**
|
||||
- Ensure you're using the correct prefix: `deepgram/nova-3` or `assemblyai/best`
|
||||
- Verify the provider is connected in **Dashboard → Providers**
|
||||
|
||||
### Транскрипцията се връща празна или е неуспешна
|
||||
### Transcription returns empty or fails
|
||||
|
||||
- Проверете поддържаните аудио формати: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`
|
||||
- Уверете се, че размерът на файла е в границите на доставчика (обикновено < 25MB)
|
||||
- Проверете валидността на API ключа на доставчика в картата на доставчика
|
||||
- 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
|
||||
|
||||
- **Мислещите етикети не се появяват** — Проверете дали целевият доставчик поддържа мисленето и настройката на бюджета за мислене
|
||||
- **Отпадане на извикванията на инструменти** — Някои преводи на формати може да премахнат неподдържаните полета; потвърдете в режим Playground
|
||||
- **Липсва системна подкана** — Клод и Джемини обработват системните подкани по различен начин; проверка на резултата за превод
|
||||
- **SDK връща необработен низ вместо обект** — Коригирано във v1.1.0: дезинфекциращото средство за отговор вече премахва нестандартните полета (`x_groq`, `usage_breakdown` и т.н.), които причиняват неуспешно валидиране на OpenAI SDK Pydantic
|
||||
- **GLM/ERNIE отхвърля `system` роля** — Коригирано във v1.1.0: нормализаторът на роли автоматично обединява системни съобщения в потребителски съобщения за несъвместими модели
|
||||
- **`developer` ролята не е разпозната** — Коригирано във v1.1.0: автоматично преобразувано в `system` за доставчици, които не са OpenAI
|
||||
- **`json_schema` не работи с Gemini** — Коригирано във v1.1.0: `response_format` сега се преобразува в `responseMimeType` + `responseSchema` на Gemini
|
||||
- **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
|
||||
|
||||
### Автоматичното ограничение на скоростта не се задейства
|
||||
### Auto rate-limit not triggering
|
||||
|
||||
- Автоматичното ограничение на скоростта се прилага само за доставчици на API ключове (не OAuth/абонамент)
|
||||
- Уверете се, че **Настройки → Устойчивост → Профили на доставчици** има активиран автоматичен лимит на скоростта
|
||||
- Проверете дали доставчикът връща `429` кодове за състояние или `Retry-After` заглавки
|
||||
- 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
|
||||
|
||||
### Настройване на експоненциално забавяне
|
||||
### Tuning exponential backoff
|
||||
|
||||
Профилите на доставчика поддържат тези настройки:
|
||||
Provider profiles support these settings:
|
||||
|
||||
- **Базово забавяне** — Първоначално време на изчакване след първата повреда (по подразбиране: 1s)
|
||||
- **Максимално забавяне** — Максимално ограничение на времето за изчакване (по подразбиране: 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)
|
||||
|
||||
### Анти-гръмотевично стадо
|
||||
### Anti-thundering herd
|
||||
|
||||
Когато много едновременни заявки попаднат на доставчик с ограничена скорост, OmniRoute използва mutex + автоматично ограничаване на скоростта, за да сериализира заявките и да предотврати каскадни грешки. Това е автоматично за доставчиците на API ключове.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Все още сте заседнали?
|
||||
## Optional RAG / LLM failure taxonomy (16 problems)
|
||||
|
||||
- **Проблеми с GitHub**: [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **Архитектура**: Вижте [link](ARCHITECTURE.md) за вътрешни подробности
|
||||
- **API Reference**: Вижте [link](API_REFERENCE.md) за всички крайни точки
|
||||
- **Табло за управление на здравето**: Проверете **Табло за управление → Здраве** за състоянието на системата в реално време
|
||||
- **Преводач**: Използвайте **Табло за управление → Преводач** за отстраняване на грешки при проблеми с формата
|
||||
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.
|
||||
|
||||
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):
|
||||
|
||||
[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
|
||||
|
||||
@@ -1,12 +1,16 @@
|
||||
# Ръководство за потребителя
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](../es/USER_GUIDE.md) | 🇫🇷 [Français](../fr/USER_GUIDE.md) | 🇮🇹 [Italiano](../it/USER_GUIDE.md) | 🇷🇺 [Русский](../ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](../de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](../in/USER_GUIDE.md) | 🇹🇭 [ไทย](../th/USER_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](../ar/USER_GUIDE.md) | 🇯🇵 [日本語](../ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/USER_GUIDE.md) | 🇧🇬 [Български](../bg/USER_GUIDE.md) | 🇩🇰 [Dansk](../da/USER_GUIDE.md) | 🇫🇮 [Suomi](../fi/USER_GUIDE.md) | 🇮🇱 [עברית](../he/USER_GUIDE.md) | 🇭🇺 [Magyar](../hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/USER_GUIDE.md) | 🇰🇷 [한국어](../ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](../nl/USER_GUIDE.md) | 🇳🇴 [Norsk](../no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/USER_GUIDE.md) | 🇷🇴 [Română](../ro/USER_GUIDE.md) | 🇵🇱 [Polski](../pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/USER_GUIDE.md) | 🇸🇪 [Svenska](../sv/USER_GUIDE.md) | 🇵🇭 [Filipino](../phi/USER_GUIDE.md)
|
||||
|
||||
Пълно ръководство за конфигуриране на доставчици, създаване на комбинации, интегриране на CLI инструменти и внедряване на OmniRoute.
|
||||
🌐 **Languages:** 🇺🇸 [English](../../README.md) · 🇧🇷 [pt-BR](../pt-BR/USER_GUIDE.md) · 🇪🇸 [es](../es/USER_GUIDE.md) · 🇫🇷 [fr](../fr/USER_GUIDE.md) · 🇩🇪 [de](../de/USER_GUIDE.md) · 🇮🇹 [it](../it/USER_GUIDE.md) · 🇷🇺 [ru](../ru/USER_GUIDE.md) · 🇨🇳 [zh-CN](../zh-CN/USER_GUIDE.md) · 🇯🇵 [ja](../ja/USER_GUIDE.md) · 🇰🇷 [ko](../ko/USER_GUIDE.md) · 🇸🇦 [ar](../ar/USER_GUIDE.md) · 🇮🇳 [in](../in/USER_GUIDE.md) · 🇹🇭 [th](../th/USER_GUIDE.md) · 🇻🇳 [vi](../vi/USER_GUIDE.md) · 🇮🇩 [id](../id/USER_GUIDE.md) · 🇲🇾 [ms](../ms/USER_GUIDE.md) · 🇳🇱 [nl](../nl/USER_GUIDE.md) · 🇵🇱 [pl](../pl/USER_GUIDE.md) · 🇸🇪 [sv](../sv/USER_GUIDE.md) · 🇳🇴 [no](../no/USER_GUIDE.md) · 🇩🇰 [da](../da/USER_GUIDE.md) · 🇫🇮 [fi](../fi/USER_GUIDE.md) · 🇵🇹 [pt](../pt/USER_GUIDE.md) · 🇷🇴 [ro](../ro/USER_GUIDE.md) · 🇭🇺 [hu](../hu/USER_GUIDE.md) · 🇧🇬 [bg](../bg/USER_GUIDE.md) · 🇸🇰 [sk](../sk/USER_GUIDE.md) · 🇺🇦 [uk-UA](../uk-UA/USER_GUIDE.md) · 🇮🇱 [he](../he/USER_GUIDE.md) · 🇵🇭 [phi](../phi/USER_GUIDE.md)
|
||||
|
||||
---
|
||||
|
||||
## Съдържание
|
||||
# User Guide
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](USER_GUIDE.md) | 🇧🇷 [Português (Brasil)](i18n/pt-BR/USER_GUIDE.md) | 🇪🇸 [Español](i18n/es/USER_GUIDE.md) | 🇫🇷 [Français](i18n/fr/USER_GUIDE.md) | 🇮🇹 [Italiano](i18n/it/USER_GUIDE.md) | 🇷🇺 [Русский](i18n/ru/USER_GUIDE.md) | 🇨🇳 [中文 (简体)](i18n/zh-CN/USER_GUIDE.md) | 🇩🇪 [Deutsch](i18n/de/USER_GUIDE.md) | 🇮🇳 [हिन्दी](i18n/in/USER_GUIDE.md) | 🇹🇭 [ไทย](i18n/th/USER_GUIDE.md) | 🇺🇦 [Українська](i18n/uk-UA/USER_GUIDE.md) | 🇸🇦 [العربية](i18n/ar/USER_GUIDE.md) | 🇯🇵 [日本語](i18n/ja/USER_GUIDE.md) | 🇻🇳 [Tiếng Việt](i18n/vi/USER_GUIDE.md) | 🇧🇬 [Български](i18n/bg/USER_GUIDE.md) | 🇩🇰 [Dansk](i18n/da/USER_GUIDE.md) | 🇫🇮 [Suomi](i18n/fi/USER_GUIDE.md) | 🇮🇱 [עברית](i18n/he/USER_GUIDE.md) | 🇭🇺 [Magyar](i18n/hu/USER_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](i18n/id/USER_GUIDE.md) | 🇰🇷 [한국어](i18n/ko/USER_GUIDE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/USER_GUIDE.md) | 🇳🇱 [Nederlands](i18n/nl/USER_GUIDE.md) | 🇳🇴 [Norsk](i18n/no/USER_GUIDE.md) | 🇵🇹 [Português (Portugal)](i18n/pt/USER_GUIDE.md) | 🇷🇴 [Română](i18n/ro/USER_GUIDE.md) | 🇵🇱 [Polski](i18n/pl/USER_GUIDE.md) | 🇸🇰 [Slovenčina](i18n/sk/USER_GUIDE.md) | 🇸🇪 [Svenska](i18n/sv/USER_GUIDE.md) | 🇵🇭 [Filipino](i18n/phi/USER_GUIDE.md)
|
||||
|
||||
Complete guide for configuring providers, creating combos, integrating CLI tools, and deploying OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Pricing at a Glance](#-pricing-at-a-glance)
|
||||
- [Use Cases](#-use-cases)
|
||||
@@ -18,40 +22,40 @@
|
||||
|
||||
---
|
||||
|
||||
## 💰 Ценообразуването с един поглед
|
||||
## 💰 Pricing at a Glance
|
||||
|
||||
| Ниво | Доставчик | Цена | Нулиране на квота | Най-добро за |
|
||||
| ------------------ | ----------------- | --------------------- | ----------------------- | ------------------------- |
|
||||
| **💳 АБОНАМЕНТ** | Claude Code (Pro) | $20/месец | 5 часа + седмично | Вече сте абонирани |
|
||||
| | Codex (Plus/Pro) | $20-200/месец | 5 часа + седмично | Потребители на OpenAI |
|
||||
| | Gemini CLI | **БЕЗПЛАТНО** | 180K/месец + 1K/ден | всички! |
|
||||
| | Копилот на GitHub | $10-19/месец | Месечно | Потребители на GitHub |
|
||||
| **🔑 КЛЮЧ ЗА API** | DeepSeek | Плащане за използване | Няма | Евтини разсъждения |
|
||||
| | Groq | Плащане за използване | Няма | Свръхбърз извод |
|
||||
| | xAI (Grok) | Плащане за използване | Няма | Грок 4 разсъждения |
|
||||
| | Мистрал | Плащане за използване | Няма | Хоствани в ЕС модели |
|
||||
| | Недоумение | Плащане за използване | Няма | Разширено търсене |
|
||||
| | Заедно AI | Плащане за използване | Няма | Модели с отворен код |
|
||||
| | Фойерверки AI | Плащане за използване | Няма | Бързи FLUX изображения |
|
||||
| | Мозъци | Плащане за използване | Няма | Скорост на вафла |
|
||||
| | Cohere | Плащане за използване | Няма | Команда R+ RAG |
|
||||
| | NVIDIA NIM | Плащане за използване | Няма | Корпоративни модели |
|
||||
| **💰 ЕВТИНО** | GLM-4.7 | $0,6/1 милион | Ежедневно 10 сутринта | Резервно копие на бюджета |
|
||||
| | MiniMax M2.1 | $0,2/1 милион | 5-часово търкаляне | Най-евтиният вариант |
|
||||
| | Кими К2 | $9/месец апартамент | 10 милиона токена/месец | Предвидими разходи |
|
||||
| **🆓 БЕЗПЛАТНО** | iFlow | $0 | Неограничен | 8 модела безплатно |
|
||||
| | Куен | $0 | Неограничен | 3 модела безплатно |
|
||||
| | Киро | $0 | Неограничен | Клод безплатно |
|
||||
| Tier | Provider | Cost | Quota Reset | Best For |
|
||||
| ------------------- | ----------------- | ----------- | ---------------- | -------------------- |
|
||||
| **💳 SUBSCRIPTION** | Claude Code (Pro) | $20/mo | 5h + weekly | Already subscribed |
|
||||
| | Codex (Plus/Pro) | $20-200/mo | 5h + weekly | OpenAI users |
|
||||
| | Gemini CLI | **FREE** | 180K/mo + 1K/day | Everyone! |
|
||||
| | GitHub Copilot | $10-19/mo | Monthly | GitHub users |
|
||||
| **🔑 API KEY** | DeepSeek | Pay per use | None | Cheap reasoning |
|
||||
| | Groq | Pay per use | None | Ultra-fast inference |
|
||||
| | xAI (Grok) | Pay per use | None | Grok 4 reasoning |
|
||||
| | Mistral | Pay per use | None | EU-hosted models |
|
||||
| | Perplexity | Pay per use | None | Search-augmented |
|
||||
| | Together AI | Pay per use | None | Open-source models |
|
||||
| | Fireworks AI | Pay per use | None | Fast FLUX images |
|
||||
| | Cerebras | Pay per use | None | Wafer-scale speed |
|
||||
| | Cohere | Pay per use | None | Command R+ RAG |
|
||||
| | NVIDIA NIM | Pay per use | None | Enterprise models |
|
||||
| **💰 CHEAP** | GLM-4.7 | $0.6/1M | Daily 10AM | Budget backup |
|
||||
| | MiniMax M2.1 | $0.2/1M | 5-hour rolling | Cheapest option |
|
||||
| | Kimi K2 | $9/mo flat | 10M tokens/mo | Predictable cost |
|
||||
| **🆓 FREE** | iFlow | $0 | Unlimited | 8 models free |
|
||||
| | Qwen | $0 | Unlimited | 3 models free |
|
||||
| | Kiro | $0 | Unlimited | Claude free |
|
||||
|
||||
**💡 Професионален съвет:** Започнете с Gemini CLI (180K безплатно/месец) + iFlow (неограничено безплатно) комбинация = $0 цена!
|
||||
**💡 Pro Tip:** Start with Gemini CLI (180K free/month) + iFlow (unlimited free) combo = $0 cost!
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Случаи на употреба
|
||||
## 🎯 Use Cases
|
||||
|
||||
### Случай 1: „Имам абонамент за Claude Pro“
|
||||
### Case 1: "I have Claude Pro subscription"
|
||||
|
||||
**Проблем:** Квотата изтича неизползвана, ограничения на скоростта по време на тежко кодиране
|
||||
**Problem:** Quota expires unused, rate limits during heavy coding
|
||||
|
||||
```
|
||||
Combo: "maximize-claude"
|
||||
@@ -63,9 +67,9 @@ Monthly cost: $20 (subscription) + ~$5 (backup) = $25 total
|
||||
vs. $20 + hitting limits = frustration
|
||||
```
|
||||
|
||||
### Случай 2: „Искам нулеви разходи“
|
||||
### Case 2: "I want zero cost"
|
||||
|
||||
**Проблем:** Не мога да си позволя абонаменти, имам нужда от надеждно AI кодиране
|
||||
**Problem:** Can't afford subscriptions, need reliable AI coding
|
||||
|
||||
```
|
||||
Combo: "free-forever"
|
||||
@@ -77,9 +81,9 @@ Monthly cost: $0
|
||||
Quality: Production-ready models
|
||||
```
|
||||
|
||||
### Случай 3: „Имам нужда от кодиране 24/7, без прекъсвания“
|
||||
### Case 3: "I need 24/7 coding, no interruptions"
|
||||
|
||||
**Проблем:** Крайни срокове, не мога да си позволя престой
|
||||
**Problem:** Deadlines, can't afford downtime
|
||||
|
||||
```
|
||||
Combo: "always-on"
|
||||
@@ -93,9 +97,9 @@ Result: 5 layers of fallback = zero downtime
|
||||
Monthly cost: $20-200 (subscriptions) + $10-20 (backup)
|
||||
```
|
||||
|
||||
### Случай 4: „Искам БЕЗПЛАТЕН AI в OpenClaw“
|
||||
### Case 4: "I want FREE AI in OpenClaw"
|
||||
|
||||
**Проблем:** Имате нужда от AI асистент в приложенията за съобщения, напълно безплатно
|
||||
**Problem:** Need AI assistant in messaging apps, completely free
|
||||
|
||||
```
|
||||
Combo: "openclaw-free"
|
||||
@@ -109,9 +113,9 @@ Access via: WhatsApp, Telegram, Slack, Discord, iMessage, Signal...
|
||||
|
||||
---
|
||||
|
||||
## 📖 Настройка на доставчик
|
||||
## 📖 Provider Setup
|
||||
|
||||
### 🔐 Доставчици на абонаменти
|
||||
### 🔐 Subscription Providers
|
||||
|
||||
#### Claude Code (Pro/Max)
|
||||
|
||||
@@ -126,7 +130,7 @@ Models:
|
||||
cc/claude-haiku-4-5-20251001
|
||||
```
|
||||
|
||||
**Професионален съвет:** Използвайте Opus за сложни задачи, Sonnet за скорост. OmniRoute проследява квота за модел!
|
||||
**Pro Tip:** Use Opus for complex tasks, Sonnet for speed. OmniRoute tracks quota per model!
|
||||
|
||||
#### OpenAI Codex (Plus/Pro)
|
||||
|
||||
@@ -140,7 +144,7 @@ Models:
|
||||
cx/gpt-5.1-codex-max
|
||||
```
|
||||
|
||||
#### Gemini CLI (БЕЗПЛАТНО 180K/месец!)
|
||||
#### Gemini CLI (FREE 180K/month!)
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect Gemini CLI
|
||||
@@ -152,9 +156,9 @@ Models:
|
||||
gc/gemini-2.5-pro
|
||||
```
|
||||
|
||||
**Най-добра стойност:** Огромно безплатно ниво! Използвайте това преди платените нива.
|
||||
**Best Value:** Huge free tier! Use this before paid tiers.
|
||||
|
||||
#### Копилот на GitHub
|
||||
#### GitHub Copilot
|
||||
|
||||
```bash
|
||||
Dashboard → Providers → Connect GitHub
|
||||
@@ -167,33 +171,33 @@ Models:
|
||||
gh/gemini-3-pro
|
||||
```
|
||||
|
||||
### 💰 Евтини доставчици
|
||||
### 💰 Cheap Providers
|
||||
|
||||
#### GLM-4.7 (Ежедневно нулиране, $0,6/1 млн.)
|
||||
#### GLM-4.7 (Daily reset, $0.6/1M)
|
||||
|
||||
1. Регистрирайте се: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. Вземете API ключ от Coding Plan
|
||||
3. Табло → Добавяне на API ключ: Доставчик: `glm`, API ключ: `your-key`
|
||||
1. Sign up: [Zhipu AI](https://open.bigmodel.cn/)
|
||||
2. Get API key from Coding Plan
|
||||
3. Dashboard → Add API Key: Provider: `glm`, API Key: `your-key`
|
||||
|
||||
**Използване:** `glm/glm-4.7` — **Професионален съвет:** Планът за кодиране предлага 3× квота на цена 1/7! Нулирайте всеки ден в 10:00 ч.
|
||||
**Use:** `glm/glm-4.7` — **Pro Tip:** Coding Plan offers 3× quota at 1/7 cost! Reset daily 10:00 AM.
|
||||
|
||||
#### MiniMax M2.1 (5 часа нулиране, $0,20/1 млн.)
|
||||
#### MiniMax M2.1 (5h reset, $0.20/1M)
|
||||
|
||||
1. Регистрирайте се: [MiniMax](https://www.minimax.io/)
|
||||
2. Вземете API ключ → Табло → Добавете API ключ
|
||||
1. Sign up: [MiniMax](https://www.minimax.io/)
|
||||
2. Get API key → Dashboard → Add API Key
|
||||
|
||||
**Използване:** `minimax/MiniMax-M2.1` — **Професионален съвет:** Най-евтината опция за дълъг контекст (1M токени)!
|
||||
**Use:** `minimax/MiniMax-M2.1` — **Pro Tip:** Cheapest option for long context (1M tokens)!
|
||||
|
||||
#### Kimi K2 ($9/месец фиксиран)
|
||||
#### Kimi K2 ($9/month flat)
|
||||
|
||||
1. Абонирайте се: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. Вземете API ключ → Табло → Добавете API ключ
|
||||
1. Subscribe: [Moonshot AI](https://platform.moonshot.ai/)
|
||||
2. Get API key → Dashboard → Add API Key
|
||||
|
||||
**Използване:** `kimi/kimi-latest` — **Професионален съвет:** Фиксирани $9/месец за 10 милиона токена = $0,90/1 милион ефективна цена!
|
||||
**Use:** `kimi/kimi-latest` — **Pro Tip:** Fixed $9/month for 10M tokens = $0.90/1M effective cost!
|
||||
|
||||
### 🆓 БЕЗПЛАТНИ доставчици
|
||||
### 🆓 FREE Providers
|
||||
|
||||
#### iFlow (8 БЕЗПЛАТНИ модела)
|
||||
#### iFlow (8 FREE models)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
@@ -201,7 +205,7 @@ Dashboard → Connect iFlow → OAuth login → Unlimited usage
|
||||
Models: if/kimi-k2-thinking, if/qwen3-coder-plus, if/glm-4.7, if/minimax-m2, if/deepseek-r1
|
||||
```
|
||||
|
||||
#### Qwen (3 БЕЗПЛАТНИ модела)
|
||||
#### Qwen (3 FREE models)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
@@ -209,7 +213,7 @@ Dashboard → Connect Qwen → Device code auth → Unlimited usage
|
||||
Models: qw/qwen3-coder-plus, qw/qwen3-coder-flash
|
||||
```
|
||||
|
||||
#### Киро (Клод БЕЗПЛАТНО)
|
||||
#### Kiro (Claude FREE)
|
||||
|
||||
```bash
|
||||
Dashboard → Connect Kiro → AWS Builder ID or Google/GitHub → Unlimited
|
||||
@@ -219,9 +223,9 @@ Models: kr/claude-sonnet-4.5, kr/claude-haiku-4.5
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Комбота
|
||||
## 🎨 Combos
|
||||
|
||||
### Пример 1: Увеличаване на абонамента → Евтино архивиране
|
||||
### Example 1: Maximize Subscription → Cheap Backup
|
||||
|
||||
```
|
||||
Dashboard → Combos → Create New
|
||||
@@ -235,7 +239,7 @@ Models:
|
||||
Use in CLI: premium-coding
|
||||
```
|
||||
|
||||
### Пример 2: Само безплатно (нулева цена)
|
||||
### Example 2: Free-Only (Zero Cost)
|
||||
|
||||
```
|
||||
Name: free-combo
|
||||
@@ -249,9 +253,9 @@ Cost: $0 forever!
|
||||
|
||||
---
|
||||
|
||||
## 🔧 CLI интеграция
|
||||
## 🔧 CLI Integration
|
||||
|
||||
### Курсор IDE
|
||||
### Cursor IDE
|
||||
|
||||
```
|
||||
Settings → Models → Advanced:
|
||||
@@ -260,9 +264,9 @@ Settings → Models → Advanced:
|
||||
Model: cc/claude-opus-4-6
|
||||
```
|
||||
|
||||
### Клод Код
|
||||
### Claude Code
|
||||
|
||||
Редактиране на `~/.claude/config.json`:
|
||||
Edit `~/.claude/config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -281,7 +285,7 @@ codex "your prompt"
|
||||
|
||||
### OpenClaw
|
||||
|
||||
Редактиране на `~/.openclaw/openclaw.json`:
|
||||
Edit `~/.openclaw/openclaw.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -303,9 +307,9 @@ codex "your prompt"
|
||||
}
|
||||
```
|
||||
|
||||
**Или използвайте таблото за управление:** CLI инструменти → OpenClaw → Автоматично конфигуриране
|
||||
**Or use Dashboard:** CLI Tools → OpenClaw → Auto-config
|
||||
|
||||
### Cline / Продължи / RooCode
|
||||
### Cline / Continue / RooCode
|
||||
|
||||
```
|
||||
Provider: OpenAI Compatible
|
||||
@@ -316,9 +320,28 @@ Model: cc/claude-opus-4-6
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Внедряване
|
||||
## 🚀 Deployment
|
||||
|
||||
### Внедряване на VPS
|
||||
### Global npm install (Recommended)
|
||||
|
||||
```bash
|
||||
npm install -g omniroute
|
||||
|
||||
# Create config directory
|
||||
mkdir -p ~/.omniroute
|
||||
|
||||
# Create .env file (see .env.example)
|
||||
cp .env.example ~/.omniroute/.env
|
||||
|
||||
# Start server
|
||||
omniroute
|
||||
# Or with custom port:
|
||||
omniroute --port 3000
|
||||
```
|
||||
|
||||
The CLI automatically loads `.env` from `~/.omniroute/.env` or `./.env`.
|
||||
|
||||
### VPS Deployment
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
@@ -337,7 +360,44 @@ npm run start
|
||||
# Or: pm2 start npm --name omniroute -- start
|
||||
```
|
||||
|
||||
### Докер
|
||||
### PM2 Deployment (Low Memory)
|
||||
|
||||
For servers with limited RAM, use the memory limit option:
|
||||
|
||||
```bash
|
||||
# With 512MB limit (default)
|
||||
pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or with custom memory limit
|
||||
OMNIROUTE_MEMORY_MB=512 pm2 start npm --name omniroute -- start
|
||||
|
||||
# Or using ecosystem.config.js
|
||||
pm2 start ecosystem.config.js
|
||||
```
|
||||
|
||||
Create `ecosystem.config.js`:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
apps: [
|
||||
{
|
||||
name: "omniroute",
|
||||
script: "npm",
|
||||
args: "start",
|
||||
env: {
|
||||
NODE_ENV: "production",
|
||||
OMNIROUTE_MEMORY_MB: "512",
|
||||
JWT_SECRET: "your-secret",
|
||||
INITIAL_PASSWORD: "your-password",
|
||||
},
|
||||
node_args: "--max-old-space-size=512",
|
||||
max_memory_restart: "300M",
|
||||
},
|
||||
],
|
||||
};
|
||||
```
|
||||
|
||||
### Docker
|
||||
|
||||
```bash
|
||||
# Build image (default = runner-cli with codex/claude/droid preinstalled)
|
||||
@@ -347,51 +407,54 @@ docker build -t omniroute:cli .
|
||||
docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-data:/app/data omniroute:cli
|
||||
```
|
||||
|
||||
За интегриран в хост режим с двоични файлове на CLI вижте раздела Docker в основните документи.
|
||||
For host-integrated mode with CLI binaries, see the Docker section in the main docs.
|
||||
|
||||
### Променливи на средата
|
||||
### Environment Variables
|
||||
|
||||
| Променлива | По подразбиране | Описание |
|
||||
| --------------------- | -------------------------------------- | ---------------------------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | Тайна за подписване на JWT (**промяна в производството**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | Първа парола за влизане |
|
||||
| `DATA_DIR` | `~/.omniroute` | Директория с данни (db, използване, регистрационни файлове) |
|
||||
| `PORT` | рамка по подразбиране | Сервизен порт (`20128` в примерите) |
|
||||
| `HOSTNAME` | рамка по подразбиране | Свързване на хост (Docker по подразбиране е `0.0.0.0`) |
|
||||
| `NODE_ENV` | по подразбиране по време на изпълнение | Задайте `production` за внедряване |
|
||||
| `BASE_URL` | `http://localhost:20128` | Вътрешен основен URL адрес от страната на сървъра |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Основен URL адрес на крайна точка за синхронизиране в облак |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC тайна за генерирани API ключове |
|
||||
| `REQUIRE_API_KEY` | `false` | Прилагане на API ключ на носител на `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Разрешава регистрационни файлове за заявки/отговори |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Принудително `Secure` бисквитка за удостоверяване (зад HTTPS обратен прокси) |
|
||||
| Variable | Default | Description |
|
||||
| ------------------------- | ------------------------------------ | ------------------------------------------------------- |
|
||||
| `JWT_SECRET` | `omniroute-default-secret-change-me` | JWT signing secret (**change in production**) |
|
||||
| `INITIAL_PASSWORD` | `123456` | First login password |
|
||||
| `DATA_DIR` | `~/.omniroute` | Data directory (db, usage, logs) |
|
||||
| `PORT` | framework default | Service port (`20128` in examples) |
|
||||
| `HOSTNAME` | framework default | Bind host (Docker defaults to `0.0.0.0`) |
|
||||
| `NODE_ENV` | runtime default | Set `production` for deploy |
|
||||
| `BASE_URL` | `http://localhost:20128` | Server-side internal base URL |
|
||||
| `CLOUD_URL` | `https://omniroute.dev` | Cloud sync endpoint base URL |
|
||||
| `API_KEY_SECRET` | `endpoint-proxy-api-key-secret` | HMAC secret for generated API keys |
|
||||
| `REQUIRE_API_KEY` | `false` | Enforce Bearer API key on `/v1/*` |
|
||||
| `ENABLE_REQUEST_LOGS` | `false` | Enables request/response logs |
|
||||
| `AUTH_COOKIE_SECURE` | `false` | Force `Secure` auth cookie (behind HTTPS reverse proxy) |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit in MB |
|
||||
| `PROMPT_CACHE_MAX_SIZE` | `50` | Max prompt cache entries |
|
||||
| `SEMANTIC_CACHE_MAX_SIZE` | `100` | Max semantic cache entries |
|
||||
|
||||
За пълната справка за променливите на средата вижте [README](../README.md).
|
||||
For the full environment variable reference, see the [README](../README.md).
|
||||
|
||||
---
|
||||
|
||||
## 📊 Налични модели
|
||||
## 📊 Available Models
|
||||
|
||||
<details>
|
||||
<summary><b>Вижте всички налични модели</b></summary>
|
||||
<summary><b>View all available models</b></summary>
|
||||
|
||||
**Claude Code (`cc/`)** — Pro/Max: `cc/claude-opus-4-6`, `cc/claude-sonnet-4-5-20250929`, `cc/claude-haiku-4-5-20251001`
|
||||
|
||||
**Codex (`cx/`)** — Plus/Pro: `cx/gpt-5.2-codex`, `cx/gpt-5.1-codex-max`
|
||||
|
||||
**Gemini CLI (`gc/`)** — БЕЗПЛАТНО: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
|
||||
**Gemini CLI (`gc/`)** — FREE: `gc/gemini-3-flash-preview`, `gc/gemini-2.5-pro`
|
||||
|
||||
**GitHub Copilot (`gh/`)**: `gh/gpt-5`, `gh/claude-4.5-sonnet`
|
||||
|
||||
**GLM (`glm/`)** — $0,6/1 млн.: `glm/glm-4.7`
|
||||
**GLM (`glm/`)** — $0.6/1M: `glm/glm-4.7`
|
||||
|
||||
**MiniMax (`minimax/`)** — $0,2/1 млн.: `minimax/MiniMax-M2.1`
|
||||
**MiniMax (`minimax/`)** — $0.2/1M: `minimax/MiniMax-M2.1`
|
||||
|
||||
**iFlow (`if/`)** — БЕЗПЛАТНО: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
|
||||
**iFlow (`if/`)** — FREE: `if/kimi-k2-thinking`, `if/qwen3-coder-plus`, `if/deepseek-r1`
|
||||
|
||||
**Qwen (`qw/`)** — БЕЗПЛАТНО: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
|
||||
**Qwen (`qw/`)** — FREE: `qw/qwen3-coder-plus`, `qw/qwen3-coder-flash`
|
||||
|
||||
**Киро (`kr/`)** — БЕЗПЛАТНО: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
|
||||
**Kiro (`kr/`)** — FREE: `kr/claude-sonnet-4.5`, `kr/claude-haiku-4.5`
|
||||
|
||||
**DeepSeek (`ds/`)**: `ds/deepseek-chat`, `ds/deepseek-reasoner`
|
||||
|
||||
@@ -399,13 +462,13 @@ docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-dat
|
||||
|
||||
**xAI (`xai/`)**: `xai/grok-4`, `xai/grok-4-0709-fast-reasoning`, `xai/grok-code-mini`
|
||||
|
||||
**Мистрал (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501`
|
||||
**Mistral (`mistral/`)**: `mistral/mistral-large-2501`, `mistral/codestral-2501`
|
||||
|
||||
**Недоумение (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
**Perplexity (`pplx/`)**: `pplx/sonar-pro`, `pplx/sonar`
|
||||
|
||||
**Заедно AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
**Together AI (`together/`)**: `together/meta-llama/Llama-3.3-70B-Instruct-Turbo`
|
||||
|
||||
**Фойерверки AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
**Fireworks AI (`fireworks/`)**: `fireworks/accounts/fireworks/models/deepseek-v3p1`
|
||||
|
||||
**Cerebras (`cerebras/`)**: `cerebras/llama-3.3-70b`
|
||||
|
||||
@@ -417,11 +480,11 @@ docker run -d --name omniroute -p 20128:20128 --env-file ./.env -v omniroute-dat
|
||||
|
||||
---
|
||||
|
||||
## 🧩 Разширени функции
|
||||
## 🧩 Advanced Features
|
||||
|
||||
### Персонализирани модели
|
||||
### Custom Models
|
||||
|
||||
Добавете всеки ID на модел към всеки доставчик, без да чакате актуализация на приложението:
|
||||
Add any model ID to any provider without waiting for an app update:
|
||||
|
||||
```bash
|
||||
# Via API
|
||||
@@ -433,11 +496,11 @@ curl -X POST http://localhost:20128/api/provider-models \
|
||||
# Remove: curl -X DELETE "http://localhost:20128/api/provider-models?provider=openai&model=gpt-4.5-preview"
|
||||
```
|
||||
|
||||
Или използвайте таблото за управление: **Доставчици → [Доставчик] → Персонализирани модели**.
|
||||
Or use Dashboard: **Providers → [Provider] → Custom Models**.
|
||||
|
||||
### Специализирани маршрути на доставчик
|
||||
### Dedicated Provider Routes
|
||||
|
||||
Насочвайте заявките директно към конкретен доставчик с валидиране на модела:
|
||||
Route requests directly to a specific provider with model validation:
|
||||
|
||||
```bash
|
||||
POST http://localhost:20128/v1/providers/openai/chat/completions
|
||||
@@ -445,9 +508,9 @@ POST http://localhost:20128/v1/providers/openai/embeddings
|
||||
POST http://localhost:20128/v1/providers/fireworks/images/generations
|
||||
```
|
||||
|
||||
Префиксът на доставчика се добавя автоматично, ако липсва. Несъответстващите модели връщат `400`.
|
||||
The provider prefix is auto-added if missing. Mismatched models return `400`.
|
||||
|
||||
### Конфигурация на мрежов прокси
|
||||
### Network Proxy Configuration
|
||||
|
||||
```bash
|
||||
# Set global proxy
|
||||
@@ -463,76 +526,76 @@ curl -X POST http://localhost:20128/api/settings/proxy/test \
|
||||
-d '{"proxy":{"type":"socks5","host":"proxy.example.com","port":"1080"}}'
|
||||
```
|
||||
|
||||
**Приоритет:** Специфичен за ключ → Специфичен за комбинация → Специфичен за доставчик → Глобален → Среда.
|
||||
**Precedence:** Key-specific → Combo-specific → Provider-specific → Global → Environment.
|
||||
|
||||
### API за каталог на модели
|
||||
### Model Catalog API
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/api/models/catalog
|
||||
```
|
||||
|
||||
Връща модели, групирани по доставчик с типове (`chat`, `embedding`, `image`).
|
||||
Returns models grouped by provider with types (`chat`, `embedding`, `image`).
|
||||
|
||||
### Облачно синхронизиране
|
||||
### Cloud Sync
|
||||
|
||||
- Синхронизиране на доставчици, комбинации и настройки на всички устройства
|
||||
- Автоматична фонова синхронизация с изчакване + бързо отказване
|
||||
- Предпочитане на сървъра `BASE_URL`/`CLOUD_URL` в производството
|
||||
- Sync providers, combos, and settings across devices
|
||||
- Automatic background sync with timeout + fail-fast
|
||||
- Prefer server-side `BASE_URL`/`CLOUD_URL` in production
|
||||
|
||||
### LLM Gateway Intelligence (Фаза 9)
|
||||
### LLM Gateway Intelligence (Phase 9)
|
||||
|
||||
- **Семантичен кеш** — Автоматично кешира нестрийминг, температура=0 отговори (заобикаляне с `X-OmniRoute-No-Cache: true`)
|
||||
- **Request Idempotency** — Дедупликира заявките в рамките на 5s чрез `Idempotency-Key` или `X-Request-Id` заглавка
|
||||
- **Проследяване на напредъка** — Включване на SSE `event: progress` събития чрез `X-OmniRoute-Progress: true` заглавка
|
||||
- **Semantic Cache** — Auto-caches non-streaming, temperature=0 responses (bypass with `X-OmniRoute-No-Cache: true`)
|
||||
- **Request Idempotency** — Deduplicates requests within 5s via `Idempotency-Key` or `X-Request-Id` header
|
||||
- **Progress Tracking** — Opt-in SSE `event: progress` events via `X-OmniRoute-Progress: true` header
|
||||
|
||||
---
|
||||
|
||||
### Площадка за преводачи
|
||||
### Translator Playground
|
||||
|
||||
Достъп чрез **Табло → Преводач**. Отстранете грешки и визуализирайте как OmniRoute превежда API заявки между доставчици.
|
||||
Access via **Dashboard → Translator**. Debug and visualize how OmniRoute translates API requests between providers.
|
||||
|
||||
| Режим | Цел |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| **Детска площадка** | Изберете изходни/целеви формати, поставете заявка и незабавно вижте преведения резултат |
|
||||
| **Чат тестер** | Изпращайте чат съобщения на живо през проксито и проверявайте пълния цикъл на заявка/отговор |
|
||||
| **Тестова стенда** | Изпълнете групови тестове в множество комбинации от формати, за да проверите правилността на превода |
|
||||
| **Монитор на живо** | Гледайте преводи в реално време, докато заявките преминават през проксито |
|
||||
| Mode | Purpose |
|
||||
| ---------------- | -------------------------------------------------------------------------------------- |
|
||||
| **Playground** | Select source/target formats, paste a request, and see the translated output instantly |
|
||||
| **Chat Tester** | Send live chat messages through the proxy and inspect the full request/response cycle |
|
||||
| **Test Bench** | Run batch tests across multiple format combinations to verify translation correctness |
|
||||
| **Live Monitor** | Watch real-time translations as requests flow through the proxy |
|
||||
|
||||
**Случаи на употреба:**
|
||||
**Use cases:**
|
||||
|
||||
- Отстраняване на грешки защо конкретна комбинация клиент/доставчик е неуспешна
|
||||
- Проверете дали мислещите тагове, извикванията на инструменти и системните подкани се превеждат правилно
|
||||
- Сравнете разликите във форматите между форматите OpenAI, Claude, Gemini и Responses API
|
||||
- Debug why a specific client/provider combination fails
|
||||
- Verify that thinking tags, tool calls, and system prompts translate correctly
|
||||
- Compare format differences between OpenAI, Claude, Gemini, and Responses API formats
|
||||
|
||||
---
|
||||
|
||||
### Стратегии за маршрутизиране
|
||||
### Routing Strategies
|
||||
|
||||
Конфигурирайте чрез **Табло → Настройки → Маршрутизация**.
|
||||
Configure via **Dashboard → Settings → Routing**.
|
||||
|
||||
| Стратегия | Описание |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| **Първо попълване** | Използва акаунти в приоритетен ред — основният акаунт обработва всички заявки, докато стане недостъпен |
|
||||
| **Round Robin** | Преминава през всички акаунти с конфигурируем лепкав лимит (по подразбиране: 3 обаждания на акаунт) |
|
||||
| **P2C (Сила на два избора)** | Избира 2 произволни акаунта и маршрути към по-здравословния — балансира натоварването с осъзнаване на здравето |
|
||||
| **Произволно** | Произволно избира акаунт за всяка заявка чрез разбъркване на Fisher-Yates |
|
||||
| **Най-малко използвани** | Насочва към акаунта с най-стария `lastUsedAt` времеви печат, разпределяйки трафика равномерно |
|
||||
| **Оптимизирани разходи** | Маршрути към акаунта с най-ниска стойност на приоритет, оптимизиране за доставчици с най-ниска цена |
|
||||
| Strategy | Description |
|
||||
| ------------------------------ | ------------------------------------------------------------------------------------------------ |
|
||||
| **Fill First** | Uses accounts in priority order — primary account handles all requests until unavailable |
|
||||
| **Round Robin** | Cycles through all accounts with a configurable sticky limit (default: 3 calls per account) |
|
||||
| **P2C (Power of Two Choices)** | Picks 2 random accounts and routes to the healthier one — balances load with awareness of health |
|
||||
| **Random** | Randomly selects an account for each request using Fisher-Yates shuffle |
|
||||
| **Least Used** | Routes to the account with the oldest `lastUsedAt` timestamp, distributing traffic evenly |
|
||||
| **Cost Optimized** | Routes to the account with the lowest priority value, optimizing for lowest-cost providers |
|
||||
|
||||
#### Псевдоними на модели със заместващи символи
|
||||
#### Wildcard Model Aliases
|
||||
|
||||
Създайте шаблони със заместващи знаци, за да пренасочите имената на моделите:
|
||||
Create wildcard patterns to remap model names:
|
||||
|
||||
```
|
||||
Pattern: claude-sonnet-* → Target: cc/claude-sonnet-4-5-20250929
|
||||
Pattern: gpt-* → Target: gh/gpt-5.1-codex
|
||||
```
|
||||
|
||||
Заместващите знаци поддържат `*` (всякакви знаци) и `?` (единичен знак).
|
||||
Wildcards support `*` (any characters) and `?` (single character).
|
||||
|
||||
#### Резервни вериги
|
||||
#### Fallback Chains
|
||||
|
||||
Дефинирайте глобални резервни вериги, които се прилагат за всички заявки:
|
||||
Define global fallback chains that apply across all requests:
|
||||
|
||||
```
|
||||
Chain: production-fallback
|
||||
@@ -543,46 +606,46 @@ Chain: production-fallback
|
||||
|
||||
---
|
||||
|
||||
### Устойчивост и прекъсвачи
|
||||
### Resilience & Circuit Breakers
|
||||
|
||||
Конфигурирайте чрез **Табло → Настройки → Устойчивост**.
|
||||
Configure via **Dashboard → Settings → Resilience**.
|
||||
|
||||
OmniRoute прилага устойчивост на ниво доставчик с четири компонента:
|
||||
OmniRoute implements provider-level resilience with four components:
|
||||
|
||||
1. **Профили на доставчици** — Конфигурация за всеки доставчик за:
|
||||
- Праг на повреда (колко повреда преди отваряне)
|
||||
- Продължителност на изчакване
|
||||
- Чувствителност на откриване на ограничение на скоростта
|
||||
- Параметри на експоненциално забавяне
|
||||
1. **Provider Profiles** — Per-provider configuration for:
|
||||
- Failure threshold (how many failures before opening)
|
||||
- Cooldown duration
|
||||
- Rate limit detection sensitivity
|
||||
- Exponential backoff parameters
|
||||
|
||||
2. **Редактируеми ограничения на скоростта** — Настройки по подразбиране на системно ниво, които могат да се конфигурират в таблото за управление:
|
||||
- **Заявки в минута (RPM)** — Максимален брой заявки в минута за акаунт
|
||||
- **Минимално време между заявките** — Минимална разлика в милисекунди между заявките
|
||||
- **Максимални едновременни заявки** — Максимални едновременни заявки за акаунт
|
||||
- Щракнете върху **Редактиране**, за да промените, след това върху **Запазване** или **Отказ**. Стойностите се запазват чрез API за устойчивост.
|
||||
2. **Editable Rate Limits** — System-level defaults configurable in the dashboard:
|
||||
- **Requests Per Minute (RPM)** — Maximum requests per minute per account
|
||||
- **Min Time Between Requests** — Minimum gap in milliseconds between requests
|
||||
- **Max Concurrent Requests** — Maximum simultaneous requests per account
|
||||
- Click **Edit** to modify, then **Save** or **Cancel**. Values persist via the resilience API.
|
||||
|
||||
3. **Прекъсвач на веригата** — Проследява повреди на доставчик и автоматично отваря веригата при достигане на праг:
|
||||
- **ЗАТВОРЕНО** (здравословно) — Заявките протичат нормално
|
||||
- **OPEN** — Доставчикът е временно блокиран след повтарящи се повреди
|
||||
- **HALF_OPEN** — Тестване дали доставчикът се е възстановил
|
||||
3. **Circuit Breaker** — Tracks failures per provider and automatically opens the circuit when a threshold is reached:
|
||||
- **CLOSED** (Healthy) — Requests flow normally
|
||||
- **OPEN** — Provider is temporarily blocked after repeated failures
|
||||
- **HALF_OPEN** — Testing if provider has recovered
|
||||
|
||||
4. **Правила и заключени идентификатори** — Показва състоянието на прекъсвача и заключените идентификатори с възможност за принудително отключване.
|
||||
4. **Policies & Locked Identifiers** — Shows circuit breaker status and locked identifiers with force-unlock capability.
|
||||
|
||||
5. **Автоматично откриване на ограничение на скоростта** — Наблюдава заглавките `429` и `Retry-After`, за да избегне проактивно достигане на ограниченията на скоростта на доставчика.
|
||||
5. **Rate Limit Auto-Detection** — Monitors `429` and `Retry-After` headers to proactively avoid hitting provider rate limits.
|
||||
|
||||
**Професионален съвет:** Използвайте бутона **Нулиране на всички**, за да изчистите всички прекъсвачи и изчаквания, когато доставчикът се възстанови от прекъсване.
|
||||
**Pro Tip:** Use **Reset All** button to clear all circuit breakers and cooldowns when a provider recovers from an outage.
|
||||
|
||||
---
|
||||
|
||||
### Експорт/импорт на база данни
|
||||
### Database Export / Import
|
||||
|
||||
Управлявайте резервни копия на бази данни в **Табло → Настройки → Система и съхранение**.
|
||||
Manage database backups in **Dashboard → Settings → System & Storage**.
|
||||
|
||||
| Действие | Описание |
|
||||
| ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Експортиране на база данни** | Изтегля текущата база данни SQLite като `.sqlite` файл |
|
||||
| **Експортиране на всички (.tar.gz)** | Изтегля пълен резервен архив, включително: база данни, настройки, комбинации, връзки с доставчик (без идентификационни данни), API ключ метаданни |
|
||||
| **Импортиране на база данни** | Качете файл `.sqlite`, за да замените текущата база данни. Автоматично се създава резервно копие преди импортиране |
|
||||
| Action | Description |
|
||||
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| **Export Database** | Downloads the current SQLite database as a `.sqlite` file |
|
||||
| **Export All (.tar.gz)** | Downloads a full backup archive including: database, settings, combos, provider connections (no credentials), API key metadata |
|
||||
| **Import Database** | Upload a `.sqlite` file to replace the current database. A pre-import backup is automatically created |
|
||||
|
||||
```bash
|
||||
# API: Export database
|
||||
@@ -596,38 +659,38 @@ curl -X POST http://localhost:20128/api/db-backups/import \
|
||||
-F "file=@backup.sqlite"
|
||||
```
|
||||
|
||||
**Проверка на импортиране:** Импортираният файл се валидира за цялост (проверка на SQLite pragma), необходими таблици (`provider_connections`, `provider_nodes`, `combos`, `api_keys`) и размер (макс. 100MB).
|
||||
**Import Validation:** The imported file is validated for integrity (SQLite pragma check), required tables (`provider_connections`, `provider_nodes`, `combos`, `api_keys`), and size (max 100MB).
|
||||
|
||||
**Случаи на употреба:**
|
||||
**Use Cases:**
|
||||
|
||||
- Мигрирайте OmniRoute между машини
|
||||
- Създаване на външни резервни копия за възстановяване след бедствие
|
||||
- Споделяне на конфигурации между членовете на екипа (експортиране на всички → споделяне на архив)
|
||||
- Migrate OmniRoute between machines
|
||||
- Create external backups for disaster recovery
|
||||
- Share configurations between team members (export all → share archive)
|
||||
|
||||
---
|
||||
|
||||
### Табло за управление на настройките
|
||||
### Settings Dashboard
|
||||
|
||||
Страницата с настройки е организирана в 5 раздела за лесна навигация:
|
||||
The settings page is organized into 5 tabs for easy navigation:
|
||||
|
||||
| Раздел | Съдържание |
|
||||
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| **Сигурност** | Настройки за вход/парола, IP контрол на достъпа, API удостоверяване за `/models` и блокиране на доставчик |
|
||||
| **Маршрутизиране** | Стратегия за глобално маршрутизиране (6 опции), псевдоними на модели със заместващи символи, резервни вериги, комбинирани настройки по подразбиране |
|
||||
| **Устойчивост** | Профили на доставчици, редактируеми лимити на скоростта, състояние на прекъсвача, политики и заключени идентификатори |
|
||||
| **AI** | Обмисляне на конфигурация на бюджета, инжектиране на глобална система, статистика на бързия кеш |
|
||||
| **Разширено** | Глобална прокси конфигурация (HTTP/SOCKS5) |
|
||||
| Tab | Contents |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------- |
|
||||
| **Security** | Login/Password settings, IP Access Control, API auth for `/models`, and Provider Blocking |
|
||||
| **Routing** | Global routing strategy (6 options), wildcard model aliases, fallback chains, combo defaults |
|
||||
| **Resilience** | Provider profiles, editable rate limits, circuit breaker status, policies & locked identifiers |
|
||||
| **AI** | Thinking budget configuration, global system prompt injection, prompt cache stats |
|
||||
| **Advanced** | Global proxy configuration (HTTP/SOCKS5) |
|
||||
|
||||
---
|
||||
|
||||
### Управление на разходите и бюджета
|
||||
### Costs & Budget Management
|
||||
|
||||
Достъп чрез **Табло → Разходи**.
|
||||
Access via **Dashboard → Costs**.
|
||||
|
||||
| Раздел | Цел |
|
||||
| ---------- | -------------------------------------------------------------------------------------------------------------- |
|
||||
| **Бюджет** | Задайте лимити на разходите за API ключ с дневни/седмични/месечни бюджети и проследяване в реално време |
|
||||
| **Цени** | Преглеждайте и редактирайте записи за ценообразуване на модела — цена за 1K входно/изходни токени на доставчик |
|
||||
| Tab | Purpose |
|
||||
| ----------- | ---------------------------------------------------------------------------------------- |
|
||||
| **Budget** | Set spending limits per API key with daily/weekly/monthly budgets and real-time tracking |
|
||||
| **Pricing** | View and edit model pricing entries — cost per 1K input/output tokens per provider |
|
||||
|
||||
```bash
|
||||
# API: Set a budget
|
||||
@@ -639,13 +702,13 @@ curl -X POST http://localhost:20128/api/usage/budget \
|
||||
curl http://localhost:20128/api/usage/budget
|
||||
```
|
||||
|
||||
**Проследяване на разходите:** Всяка заявка регистрира използването на токени и изчислява разходите с помощта на таблицата с цените. Вижте разбивки в **Табло за управление → Използване** по доставчик, модел и API ключ.
|
||||
**Cost Tracking:** Every request logs token usage and calculates cost using the pricing table. View breakdowns in **Dashboard → Usage** by provider, model, and API key.
|
||||
|
||||
---
|
||||
|
||||
### Аудио транскрипция
|
||||
### Audio Transcription
|
||||
|
||||
OmniRoute поддържа аудио транскрипция чрез OpenAI-съвместима крайна точка:
|
||||
OmniRoute supports audio transcription via the OpenAI-compatible endpoint:
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
@@ -659,40 +722,92 @@ curl -X POST http://localhost:20128/v1/audio/transcriptions \
|
||||
-F "model=deepgram/nova-3"
|
||||
```
|
||||
|
||||
Налични доставчици: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
|
||||
Available providers: **Deepgram** (`deepgram/`), **AssemblyAI** (`assemblyai/`).
|
||||
|
||||
Поддържани аудио формати: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
Supported audio formats: `mp3`, `wav`, `m4a`, `flac`, `ogg`, `webm`.
|
||||
|
||||
---
|
||||
|
||||
### Комбинирани стратегии за балансиране
|
||||
### Combo Balancing Strategies
|
||||
|
||||
Конфигурирайте балансирането за комбо в **Табло за управление → Комбота → Създаване/Редактиране → Стратегия**.
|
||||
Configure per-combo balancing in **Dashboard → Combos → Create/Edit → Strategy**.
|
||||
|
||||
| Стратегия | Описание |
|
||||
| ---------------------------- | -------------------------------------------------------------------------------- |
|
||||
| **Round-Robin** | Върти се през моделите последователно |
|
||||
| **Приоритет** | Винаги пробва първия модел; връща се само при грешка |
|
||||
| **Произволно** | Избира произволен модел от комбинацията за всяка заявка |
|
||||
| **Претеглено** | Маршрути пропорционално въз основа на зададени тегла за модел |
|
||||
| **Най-малко използвани** | Насочва към модела с най-малко скорошни заявки (използва комбинирани показатели) |
|
||||
| **Оптимизиран за разходите** | Маршрути до най-евтиния наличен модел (използва ценова таблица) |
|
||||
| Strategy | Description |
|
||||
| ------------------ | ------------------------------------------------------------------------ |
|
||||
| **Round-Robin** | Rotates through models sequentially |
|
||||
| **Priority** | Always tries the first model; falls back only on error |
|
||||
| **Random** | Picks a random model from the combo for each request |
|
||||
| **Weighted** | Routes proportionally based on assigned weights per model |
|
||||
| **Least-Used** | Routes to the model with the fewest recent requests (uses combo metrics) |
|
||||
| **Cost-Optimized** | Routes to the cheapest available model (uses pricing table) |
|
||||
|
||||
Глобалните настройки по подразбиране на комбинацията могат да бъдат зададени в **Табло → Настройки → Маршрут → Настройки по подразбиране на комбинация**.
|
||||
Global combo defaults can be set in **Dashboard → Settings → Routing → Combo Defaults**.
|
||||
|
||||
---
|
||||
|
||||
### Здравно табло
|
||||
### Health Dashboard
|
||||
|
||||
Достъп чрез **Табло → Здраве**. Преглед на здравето на системата в реално време с 6 карти:
|
||||
Access via **Dashboard → Health**. Real-time system health overview with 6 cards:
|
||||
|
||||
| Карта | Какво показва |
|
||||
| ---------------------------- | -------------------------------------------------------------------------- |
|
||||
| **Състояние на системата** | Време на работа, версия, използване на паметта, директория с данни |
|
||||
| **Здраве на доставчика** | Състояние на прекъсвача за всеки доставчик (затворен/отворен/полуотворен) |
|
||||
| **Ограничения на скоростта** | Активен лимит на изчакване за акаунт с оставащо време |
|
||||
| **Активни блокировки** | Доставчици, временно блокирани от политиката за блокиране |
|
||||
| **Кеш на подписа** | Статистика на кеша за дедупликация (активни ключове, процент на попадения) |
|
||||
| **Телеметрия за забавяне** | p50/p95/p99 агрегиране на латентност за доставчик |
|
||||
| Card | What It Shows |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| **System Status** | Uptime, version, memory usage, data directory |
|
||||
| **Provider Health** | Per-provider circuit breaker state (Closed/Open/Half-Open) |
|
||||
| **Rate Limits** | Active rate limit cooldowns per account with remaining time |
|
||||
| **Active Lockouts** | Providers temporarily blocked by the lockout policy |
|
||||
| **Signature Cache** | Deduplication cache stats (active keys, hit rate) |
|
||||
| **Latency Telemetry** | p50/p95/p99 latency aggregation per provider |
|
||||
|
||||
**Професионален съвет:** Страницата Health се опреснява автоматично на всеки 10 секунди. Използвайте картата на прекъсвача, за да идентифицирате кои доставчици имат проблеми.
|
||||
**Pro Tip:** The Health page auto-refreshes every 10 seconds. Use the circuit breaker card to identify which providers are experiencing issues.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktop Application (Electron)
|
||||
|
||||
OmniRoute is available as a native desktop application for Windows, macOS, and Linux.
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# From the electron directory:
|
||||
cd electron
|
||||
npm install
|
||||
|
||||
# Development mode (connect to running Next.js dev server):
|
||||
npm run dev
|
||||
|
||||
# Production mode (uses standalone build):
|
||||
npm start
|
||||
```
|
||||
|
||||
### Building Installers
|
||||
|
||||
```bash
|
||||
cd electron
|
||||
npm run build # Current platform
|
||||
npm run build:win # Windows (.exe NSIS)
|
||||
npm run build:mac # macOS (.dmg universal)
|
||||
npm run build:linux # Linux (.AppImage)
|
||||
```
|
||||
|
||||
Output → `electron/dist-electron/`
|
||||
|
||||
### Key Features
|
||||
|
||||
| Feature | Description |
|
||||
| --------------------------- | ---------------------------------------------------- |
|
||||
| **Server Readiness** | Polls server before showing window (no blank screen) |
|
||||
| **System Tray** | Minimize to tray, change port, quit from tray menu |
|
||||
| **Port Management** | Change server port from tray (auto-restarts server) |
|
||||
| **Content Security Policy** | Restrictive CSP via session headers |
|
||||
| **Single Instance** | Only one app instance can run at a time |
|
||||
| **Offline Mode** | Bundled Next.js server works without internet |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
| --------------------- | ------- | -------------------------------- |
|
||||
| `OMNIROUTE_PORT` | `20128` | Server port |
|
||||
| `OMNIROUTE_MEMORY_MB` | `512` | Node.js heap limit (64–16384 MB) |
|
||||
|
||||
📖 Full documentation: [`electron/README.md`](../electron/README.md)
|
||||
|
||||
401
docs/i18n/bg/VM_DEPLOYMENT_GUIDE.md
Normal file
401
docs/i18n/bg/VM_DEPLOYMENT_GUIDE.md
Normal file
@@ -0,0 +1,401 @@
|
||||
# OmniRoute — Ръководство за внедряване на VM с Cloudflare
|
||||
|
||||
🌐 **Languages:** 🇺🇸 [English](../../VM_DEPLOYMENT_GUIDE.md) | 🇧🇷 [Português (Brasil)](../pt-BR/VM_DEPLOYMENT_GUIDE.md) | 🇪🇸 [Español](../es/VM_DEPLOYMENT_GUIDE.md) | 🇫🇷 [Français](../fr/VM_DEPLOYMENT_GUIDE.md) | 🇮🇹 [Italiano](../it/VM_DEPLOYMENT_GUIDE.md) | 🇷🇺 [Русский](../ru/VM_DEPLOYMENT_GUIDE.md) | 🇨🇳 [中文 (简体)](../zh-CN/VM_DEPLOYMENT_GUIDE.md) | 🇩🇪 [Deutsch](../de/VM_DEPLOYMENT_GUIDE.md) | 🇮🇳 [हिन्दी](../in/VM_DEPLOYMENT_GUIDE.md) | 🇹🇭 [ไทย](../th/VM_DEPLOYMENT_GUIDE.md) | 🇺🇦 [Українська](../uk-UA/VM_DEPLOYMENT_GUIDE.md) | 🇸🇦 [العربية](../ar/VM_DEPLOYMENT_GUIDE.md) | 🇯🇵 [日本語](../ja/VM_DEPLOYMENT_GUIDE.md) | 🇻🇳 [Tiếng Việt](../vi/VM_DEPLOYMENT_GUIDE.md) | 🇧🇬 [Български](../bg/VM_DEPLOYMENT_GUIDE.md) | 🇩🇰 [Dansk](../da/VM_DEPLOYMENT_GUIDE.md) | 🇫🇮 [Suomi](../fi/VM_DEPLOYMENT_GUIDE.md) | 🇮🇱 [עברית](../he/VM_DEPLOYMENT_GUIDE.md) | 🇭🇺 [Magyar](../hu/VM_DEPLOYMENT_GUIDE.md) | 🇮🇩 [Bahasa Indonesia](../id/VM_DEPLOYMENT_GUIDE.md) | 🇰🇷 [한국어](../ko/VM_DEPLOYMENT_GUIDE.md) | 🇲🇾 [Bahasa Melayu](../ms/VM_DEPLOYMENT_GUIDE.md) | 🇳🇱 [Nederlands](../nl/VM_DEPLOYMENT_GUIDE.md) | 🇳🇴 [Norsk](../no/VM_DEPLOYMENT_GUIDE.md) | 🇵🇹 [Português (Portugal)](../pt/VM_DEPLOYMENT_GUIDE.md) | 🇷🇴 [Română](../ro/VM_DEPLOYMENT_GUIDE.md) | 🇵🇱 [Polski](../pl/VM_DEPLOYMENT_GUIDE.md) | 🇸🇰 [Slovenčina](../sk/VM_DEPLOYMENT_GUIDE.md) | 🇸🇪 [Svenska](../sv/VM_DEPLOYMENT_GUIDE.md) | 🇵🇭 [Filipino](../phi/VM_DEPLOYMENT_GUIDE.md) | 🇨🇿 [Čeština](../cs/VM_DEPLOYMENT_GUIDE.md)
|
||||
|
||||
Пълно ръководство за инсталиране и конфигуриране на OmniRoute на VM (VPS) с домейн, управляван чрез Cloudflare.
|
||||
|
||||
---
|
||||
|
||||
## Предпоставки
|
||||
|
||||
| Артикул | Минимум | Препоръчва се |
|
||||
| ---------- | ------------------------ | ---------------- |
|
||||
| **CPU** | 1 vCPU | 2 vCPU |
|
||||
| **RAM** | 1 GB | 2 GB |
|
||||
| **Диск** | 10 GB SSD | 25 GB SSD |
|
||||
| **OS** | Ubuntu 22.04 LTS | Ubuntu 24.04 LTS |
|
||||
| **Домейн** | Регистриран в Cloudflare | — |
|
||||
| **Докер** | Docker Engine 24+ | Докер 27+ |
|
||||
|
||||
**Тествани доставчици**: Akamai (Linode), DigitalOcean, Vultr, Hetzner, AWS Lightsail.
|
||||
|
||||
---
|
||||
|
||||
## 1. Конфигурирайте VM
|
||||
|
||||
### 1.1 Създайте екземпляра
|
||||
|
||||
На предпочитания от вас VPS доставчик:
|
||||
|
||||
- Изберете 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.3 Актуализирайте системата
|
||||
|
||||
```bash
|
||||
apt update && apt upgrade -y
|
||||
```
|
||||
|
||||
### 1.4 Инсталирайте Docker
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
apt install -y ca-certificates curl gnupg
|
||||
|
||||
# Add official Docker repository
|
||||
install -m 0755 -d /etc/apt/keyrings
|
||||
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
|
||||
chmod a+r /etc/apt/keyrings/docker.gpg
|
||||
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $ (. /etc/os-release && echo “$VERSION_CODENAME”) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
|
||||
apt update
|
||||
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||
```
|
||||
|
||||
### 1.5 Инсталирайте nginx
|
||||
|
||||
```bash
|
||||
apt install -y nginx
|
||||
```
|
||||
|
||||
### 1.6 Конфигуриране на защитна стена (UFW)
|
||||
|
||||
```bash
|
||||
ufw default deny incoming
|
||||
ufw default allow outgoing
|
||||
ufw allow 22/tcp # SSH
|
||||
ufw allow 80/tcp # HTTP (redirect)
|
||||
ufw allow 443/tcp # HTTPS
|
||||
ufw enable
|
||||
```
|
||||
|
||||
> **Съвет**: За максимална сигурност ограничете портове 80 и 443 само до IP адреси на Cloudflare. Вижте раздела [Advanced Security](#advanced-security).
|
||||
|
||||
---
|
||||
|
||||
## 2. Инсталирайте OmniRoute
|
||||
|
||||
### 2.1 Създайте конфигурационна директория
|
||||
|
||||
```bash
|
||||
mkdir -p /opt/omniroute
|
||||
```
|
||||
|
||||
### 2.2 Създайте файл с променливи на средата
|
||||
|
||||
```bash
|
||||
cat > /opt/omniroute/.env << ‘EOF’
|
||||
# === Security ===
|
||||
JWT_SECRET=CHANGE-TO-A-UNIQUE-64-CHAR-SECRET-KEY
|
||||
INITIAL_PASSWORD=YourSecurePassword123!
|
||||
API_KEY_SECRET=REPLACE-WITH-ANOTHER-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY=REPLACE-WITH-THIRD-SECRET-KEY
|
||||
STORAGE_ENCRYPTION_KEY_VERSION=v1
|
||||
MACHINE_ID_SALT=CHANGE-TO-A-UNIQUE-SALT
|
||||
|
||||
# === App ===
|
||||
PORT=20128
|
||||
NODE_ENV=production
|
||||
HOSTNAME=0.0.0.0
|
||||
DATA_DIR=/app/data
|
||||
STORAGE_DRIVER=sqlite
|
||||
ENABLE_REQUEST_LOGS=true
|
||||
AUTH_COOKIE_SECURE=false
|
||||
REQUIRE_API_KEY=false
|
||||
|
||||
# === Domain (change to your domain) ===
|
||||
BASE_URL=https://llms.seudominio.com
|
||||
NEXT_PUBLIC_BASE_URL=https://llms.seudominio.com
|
||||
|
||||
# === Cloud Sync (optional) ===
|
||||
# CLOUD_URL=https://cloud.omniroute.online
|
||||
# NEXT_PUBLIC_CLOUD_URL=https://cloud.omniroute.online
|
||||
EOF
|
||||
```
|
||||
|
||||
> ⚠️ **ВАЖНО**: Генерирайте уникални секретни ключове! Използвайте `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
|
||||
```
|
||||
|
||||
### 2.4 Проверете дали работи
|
||||
|
||||
```bash
|
||||
docker ps | grep omniroute
|
||||
docker logs omniroute --tail 20
|
||||
```
|
||||
|
||||
Трябва да показва: `[DB] SQLite database ready` и `listening on port 20128`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Конфигурирайте nginx (обратен прокси)
|
||||
|
||||
### 3.1 Генериране на SSL сертификат (Cloudflare Origin)
|
||||
|
||||
В таблото за управление на Cloudflare:
|
||||
|
||||
1. Отидете на **SSL/TLS → Origin Server**
|
||||
2. Щракнете върху **Създаване на сертификат**
|
||||
3. Запазете настройките по подразбиране (15 години, \*.yourdomain.com)
|
||||
4. Копирайте **Сертификата за произход** и **Личния ключ**
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### 3.2 Конфигурация на Nginx
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/sites-available/omniroute << ‘NGINX’
|
||||
# Default server — blocks direct access via IP
|
||||
server {
|
||||
listen 80 default_server;
|
||||
listen [::]:80 default_server;
|
||||
listen 443 ssl default_server;
|
||||
listen [::]:443 ssl default_server;
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_key /etc/nginx/ssl/origin.key;
|
||||
server_name _;
|
||||
return 444;
|
||||
}
|
||||
|
||||
# OmniRoute — HTTPS
|
||||
server {
|
||||
listen 443 ssl;
|
||||
listen [::]:443 ssl;
|
||||
server_name llms.yourdomain.com; # Change to your domain
|
||||
|
||||
ssl_certificate /etc/nginx/ssl/origin.crt;
|
||||
ssl_certificate_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 X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket support
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection “upgrade”;
|
||||
|
||||
# SSE (Server-Sent Events) — streaming AI responses
|
||||
proxy_buffering off;
|
||||
proxy_cache off;
|
||||
proxy_read_timeout 300s;
|
||||
proxy_send_timeout 300s;
|
||||
}
|
||||
}
|
||||
|
||||
# HTTP → HTTPS redirect
|
||||
server {
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
server_name llms.yourdomain.com;
|
||||
return 301 https://$server_name$request_uri;
|
||||
}
|
||||
NGINX
|
||||
```
|
||||
|
||||
### 3.3 Активиране и тестване
|
||||
|
||||
```bash
|
||||
# Remove default configuration
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
|
||||
# Enable OmniRoute
|
||||
ln -sf /etc/nginx/sites-available/omniroute /etc/nginx/sites-enabled/omniroute
|
||||
|
||||
# Test and reload
|
||||
nginx -t && systemctl reload nginx
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Конфигурирайте Cloudflare DNS
|
||||
|
||||
### 4.1 Добавете DNS запис
|
||||
|
||||
В таблото за управление на Cloudflare → DNS:
|
||||
|
||||
| Тип | Име | Съдържание | Прокси |
|
||||
| --- | ------ | ---------------------- | ------------ |
|
||||
| A | `llms` | `203.0.113.10` (VM IP) | ✅ Проксиран |
|
||||
|
||||
### 4.2 Конфигурирайте SSL
|
||||
|
||||
Под **SSL/TLS → Общ преглед**:
|
||||
|
||||
- Режим: **Пълен (строг)**
|
||||
|
||||
Под **SSL/TLS → Edge Certificates**:
|
||||
|
||||
- Винаги използвайте HTTPS: ✅ Вкл
|
||||
- Минимална TLS версия: TLS 1.2
|
||||
- Автоматично пренаписване на HTTPS: ✅ Включено
|
||||
|
||||
### 4.3 Тестване
|
||||
|
||||
```bash
|
||||
curl -sI https://llms.seudominio.com/health
|
||||
# Should return HTTP/2 200
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Операции и поддръжка
|
||||
|
||||
### Надстройте до нова версия
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### Преглед на регистрационни файлове
|
||||
|
||||
```bash
|
||||
docker logs -f omniroute # Real-time stream
|
||||
docker logs omniroute --tail 50 # Last 50 lines
|
||||
```
|
||||
|
||||
### Ръчно архивиране на база данни
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### Възстановяване от резервно копие
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Разширена сигурност
|
||||
|
||||
### Ограничете nginx до IP адреси на Cloudflare
|
||||
|
||||
```bash
|
||||
cat > /etc/nginx/cloudflare-ips.conf << ‘CF’
|
||||
# Cloudflare IPv4 ranges — update periodically
|
||||
# https://www.cloudflare.com/ips-v4/
|
||||
set_real_ip_from 173.245.48.0/20;
|
||||
set_real_ip_from 103.21.244.0/22;
|
||||
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_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
|
||||
```
|
||||
|
||||
Добавете следното към `nginx.conf` в блока `http {}`:
|
||||
|
||||
```nginx
|
||||
include /etc/nginx/cloudflare-ips.conf;
|
||||
```
|
||||
|
||||
### Инсталирайте fail2ban
|
||||
|
||||
```bash
|
||||
apt install -y fail2ban
|
||||
systemctl enable fail2ban
|
||||
systemctl start fail2ban
|
||||
|
||||
# Check status
|
||||
fail2ban-client status sshd
|
||||
```
|
||||
|
||||
### Блокирайте директния достъп до порта на Docker
|
||||
|
||||
```bash
|
||||
# Prevent direct external access to port 20128
|
||||
iptables -I DOCKER-USER -p tcp --dport 20128 -j DROP
|
||||
iptables -I DOCKER-USER -i lo -p tcp --dport 20128 -j ACCEPT
|
||||
|
||||
# Persist the rules
|
||||
apt install -y iptables-persistent
|
||||
netfilter-persistent save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Разположете в Cloudflare Workers (по избор)
|
||||
|
||||
За отдалечен достъп чрез Cloudflare Workers (без директно излагане на VM):
|
||||
|
||||
```bash
|
||||
# In the local repository
|
||||
cd omnirouteCloud
|
||||
npm install
|
||||
npx wrangler login
|
||||
npx wrangler deploy
|
||||
```
|
||||
|
||||
Вижте пълната документация на [omnirouteCloud/README.md](../omnirouteCloud/README.md).
|
||||
|
||||
---
|
||||
|
||||
## Резюме на порта
|
||||
|
||||
| Пристанище | Обслужване | Достъп |
|
||||
| ---------- | ----------- | ------------------------------ |
|
||||
| 22 | SSH | Публичен (с fail2ban) |
|
||||
| 80 | nginx HTTP | Пренасочване → HTTPS |
|
||||
| 443 | nginx HTTPS | Чрез прокси Cloudflare |
|
||||
| 20128 | OmniRoute | Само локален хост (чрез nginx) |
|
||||
196
docs/i18n/cs/A2A-SERVER.md
Normal file
196
docs/i18n/cs/A2A-SERVER.md
Normal file
@@ -0,0 +1,196 @@
|
||||
# Dokumentace k serveru OmniRoute A2A
|
||||
|
||||
> Protokol Agent-to-Agent v0.3 — OmniRoute jako inteligentní směrovací agent
|
||||
|
||||
## Objevování agentů
|
||||
|
||||
```bash
|
||||
curl http://localhost:20128/.well-known/agent.json
|
||||
```
|
||||
|
||||
Vrátí kartu agenta popisující schopnosti, dovednosti a požadavky na ověřování OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## Ověřování
|
||||
|
||||
Všechny požadavky `/a2a` vyžadují klíč API zadaný prostřednictvím hlavičky `Authorization` :
|
||||
|
||||
```
|
||||
Authorization: Bearer YOUR_OMNIROUTE_API_KEY
|
||||
```
|
||||
|
||||
Pokud na serveru není nakonfigurován žádný klíč API, ověřování se obejde.
|
||||
|
||||
---
|
||||
|
||||
## Metody JSON-RPC 2.0
|
||||
|
||||
### `message/send` — synchronní spuštění
|
||||
|
||||
Odešle zprávu dovednosti a čeká na úplnou odpověď.
|
||||
|
||||
```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 hello world in Python"}],
|
||||
"metadata": {"model": "auto", "combo": "fast-coding"}
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**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" }
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `message/stream` — SSE streamování
|
||||
|
||||
Stejné jako `message/send` , 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" \
|
||||
-d '{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "1",
|
||||
"method": "message/stream",
|
||||
"params": {
|
||||
"skill": "smart-routing",
|
||||
"messages": [{"role": "user", "content": "Explain quantum computing"}]
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
**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` — Dotaz na stav úlohy
|
||||
|
||||
```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"}}'
|
||||
```
|
||||
|
||||
### `tasks/cancel` — Zrušit úkol
|
||||
|
||||
```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"}}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dostupné dovednosti
|
||||
|
||||
Dovednost | Popis
|
||||
:-- | :--
|
||||
`smart-routing` | Směruje výzvy prostřednictvím inteligentního kanálu OmniRoute. Vrací odpověď s vysvětlením směrování, náklady a trasou odolnosti.
|
||||
`quota-management` | Odpovídá na dotazy v přirozeném jazyce týkající se kvót poskytovatelů, navrhuje bezplatné kombinace a poskytuje hodnocení kvót.
|
||||
|
||||
---
|
||||
|
||||
## Životní cyklus úkolu
|
||||
|
||||
```
|
||||
submitted → working → completed
|
||||
→ failed
|
||||
→ cancelled
|
||||
```
|
||||
|
||||
- Úkoly vyprší po 5 minutách (konfigurovatelné)
|
||||
- Stavy terminálu: `completed` , `failed` , `cancelled`
|
||||
- Záznam událostí sleduje každý přechod stavu
|
||||
|
||||
---
|
||||
|
||||
## Chybové kódy
|
||||
|
||||
Kód | Význam
|
||||
:-- | :--
|
||||
-32700 | Chyba při analýze (neplatný JSON)
|
||||
-32600 | Neplatný požadavek / Neautorizovaný
|
||||
-32601 | Metoda nebo dovednost nenalezena
|
||||
-32602 | Neplatné parametry
|
||||
-32603 | Interní chyba
|
||||
|
||||
---
|
||||
|
||||
## Příklady integrace
|
||||
|
||||
### Python (požadavky)
|
||||
|
||||
```python
|
||||
import requests
|
||||
|
||||
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"})
|
||||
|
||||
result = resp.json()["result"]
|
||||
print(result["artifacts"][0]["content"])
|
||||
print(result["metadata"]["routing_explanation"])
|
||||
```
|
||||
|
||||
### TypeScript (načtení)
|
||||
|
||||
```typescript
|
||||
const resp = await fetch("http://localhost:20128/a2a", {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
Authorization: "Bearer YOUR_KEY",
|
||||
},
|
||||
body: 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);
|
||||
```
|
||||
451
docs/i18n/cs/API_REFERENCE.md
Normal file
451
docs/i18n/cs/API_REFERENCE.md
Normal file
@@ -0,0 +1,451 @@
|
||||
# Referenční informace k API
|
||||
|
||||
🌐 **Jazyky:** 🇺🇸 [angličtina](API_REFERENCE.md) | 🇧🇷 [Português (Brazílie)](i18n/pt-BR/API_REFERENCE.md) | 🇪🇸 [Español](i18n/es/API_REFERENCE.md) | 🇫🇷 [Français](i18n/fr/API_REFERENCE.md) | 🇮🇹 [Italiano](i18n/it/API_REFERENCE.md) | 🇷🇺 [Русский](i18n/ru/API_REFERENCE.md) | 🇨🇳[中文 (简体)](i18n/zh-CN/API_REFERENCE.md) | 🇩🇪 [Deutsch](i18n/de/API_REFERENCE.md) | 🇮🇳 [हिन्दी](i18n/in/API_REFERENCE.md) | 🇹🇭 [ไทย](i18n/th/API_REFERENCE.md) | 🇺🇦 [Українська](i18n/uk-UA/API_REFERENCE.md) | 🇸🇦 [العربية](i18n/ar/API_REFERENCE.md) | 🇯🇵[日本語](i18n/ja/API_REFERENCE.md)| 🇻🇳 [Tiếng Việt](i18n/vi/API_REFERENCE.md) | 🇧🇬 [Български](i18n/bg/API_REFERENCE.md) | 🇩🇰 [Dánsko](i18n/da/API_REFERENCE.md) | 🇫🇮 [Suomi](i18n/fi/API_REFERENCE.md) | 🇮🇱 [עברית](i18n/he/API_REFERENCE.md) | 🇭🇺 [maďarština](i18n/hu/API_REFERENCE.md) | 🇮🇩 [Bahasa Indonésie](i18n/id/API_REFERENCE.md) | 🇰🇷 [한국어](i18n/ko/API_REFERENCE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/API_REFERENCE.md) | 🇳🇱 [Nizozemsko](i18n/nl/API_REFERENCE.md) | 🇳🇴 [Norsk](i18n/no/API_REFERENCE.md) | 🇵🇹 [Português (Portugalsko)](i18n/pt/API_REFERENCE.md) | 🇷🇴 [Română](i18n/ro/API_REFERENCE.md) | 🇵🇱 [Polski](i18n/pl/API_REFERENCE.md) | 🇸🇰 [Slovenčina](i18n/sk/API_REFERENCE.md) | 🇸🇪 [Svenska](i18n/sv/API_REFERENCE.md) | 🇵🇭 [Filipínec](i18n/phi/API_REFERENCE.md) | 🇨🇿 [Čeština](i18n/cs/API_REFERENCE.md)
|
||||
|
||||
Kompletní referenční příručka pro všechny koncové body rozhraní OmniRoute API.
|
||||
|
||||
---
|
||||
|
||||
## Obsah
|
||||
|
||||
- [Dokončení chatu](#chat-completions)
|
||||
- [Vložení](#embeddings)
|
||||
- [Generování obrázků](#image-generation)
|
||||
- [Seznam modelů](#list-models)
|
||||
- [Koncové body kompatibility](#compatibility-endpoints)
|
||||
- [Sémantická mezipaměť](#semantic-cache)
|
||||
- [Řídicí panel a správa](#dashboard--management)
|
||||
- [Zpracování žádosti](#request-processing)
|
||||
- [Ověřování](#authentication)
|
||||
|
||||
---
|
||||
|
||||
## Dokončení chatu
|
||||
|
||||
```bash
|
||||
POST /v1/chat/completions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "cc/claude-opus-4-6",
|
||||
"messages": [
|
||||
{"role": "user", "content": "Write a function to..."}
|
||||
],
|
||||
"stream": true
|
||||
}
|
||||
```
|
||||
|
||||
### Vlastní záhlaví
|
||||
|
||||
Záhlaví | Směr | Popis
|
||||
--- | --- | ---
|
||||
`X-OmniRoute-No-Cache` | Žádost | Nastavením na `true` se vynechá mezipaměť
|
||||
`X-OmniRoute-Progress` | Žádost | Nastaveno na `true` pro události průběhu
|
||||
`Idempotency-Key` | Žádost | Klíč pro deduplikaci (okno 5 s)
|
||||
`X-Request-Id` | Žádost | Alternativní klíč pro odstranění duplicitních dat
|
||||
`X-OmniRoute-Cache` | Odpověď | `HIT` or `MISS` (nestreamované)
|
||||
`X-OmniRoute-Idempotent` | Odpověď | `true` , pokud je odstraněna duplikace
|
||||
`X-OmniRoute-Progress` | Odpověď | `enabled` pokud je zapnuto sledování průběhu
|
||||
|
||||
---
|
||||
|
||||
## Vložení
|
||||
|
||||
```bash
|
||||
POST /v1/embeddings
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "nebius/Qwen/Qwen3-Embedding-8B",
|
||||
"input": "The food was delicious"
|
||||
}
|
||||
```
|
||||
|
||||
Dostupní poskytovatelé: Nebius, OpenAI, Mistral, Together AI, Fireworks, NVIDIA.
|
||||
|
||||
```bash
|
||||
# List all embedding models
|
||||
GET /v1/embeddings
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Generování obrázků
|
||||
|
||||
```bash
|
||||
POST /v1/images/generations
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "openai/dall-e-3",
|
||||
"prompt": "A beautiful sunset over mountains",
|
||||
"size": "1024x1024"
|
||||
}
|
||||
```
|
||||
|
||||
Dostupní poskytovatelé: OpenAI (DALL-E), xAI (Grok Image), Together AI (FLUX), Fireworks AI.
|
||||
|
||||
```bash
|
||||
# List all image models
|
||||
GET /v1/images/generations
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Seznam modelů
|
||||
|
||||
```bash
|
||||
GET /v1/models
|
||||
Authorization: Bearer your-api-key
|
||||
|
||||
→ Returns all chat, embedding, and image models + combos in OpenAI format
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Koncové body kompatibility
|
||||
|
||||
Metoda | Cesta | Formát
|
||||
--- | --- | ---
|
||||
ZVEŘEJNIT | `/v1/chat/completions` | OpenAI
|
||||
ZVEŘEJNIT | `/v1/messages` | Antropický
|
||||
ZVEŘEJNIT | `/v1/responses` | Reakce OpenAI
|
||||
ZVEŘEJNIT | `/v1/embeddings` | OpenAI
|
||||
ZVEŘEJNIT | `/v1/images/generations` | OpenAI
|
||||
ZÍSKAT | `/v1/models` | OpenAI
|
||||
ZVEŘEJNIT | `/v1/messages/count_tokens` | Antropický
|
||||
ZÍSKAT | `/v1beta/models` | Blíženci
|
||||
ZVEŘEJNIT | `/v1beta/models/{...path}` | Gemini generuje obsah
|
||||
ZVEŘEJNIT | `/v1/api/chat` | Ollama
|
||||
|
||||
### Vyhrazené trasy poskytovatelů
|
||||
|
||||
```bash
|
||||
POST /v1/providers/{provider}/chat/completions
|
||||
POST /v1/providers/{provider}/embeddings
|
||||
POST /v1/providers/{provider}/images/generations
|
||||
```
|
||||
|
||||
Pokud chybí prefix poskytovatele, automaticky se přidá. Neshodné modely vrátí chybu `400` .
|
||||
|
||||
---
|
||||
|
||||
## Sémantická mezipaměť
|
||||
|
||||
```bash
|
||||
# Get cache stats
|
||||
GET /api/cache
|
||||
|
||||
# Clear all caches
|
||||
DELETE /api/cache
|
||||
```
|
||||
|
||||
Příklad odpovědi:
|
||||
|
||||
```json
|
||||
{
|
||||
"semanticCache": {
|
||||
"memorySize": 42,
|
||||
"memoryMaxSize": 500,
|
||||
"dbSize": 128,
|
||||
"hitRate": 0.65
|
||||
},
|
||||
"idempotency": {
|
||||
"activeKeys": 3,
|
||||
"windowMs": 5000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Řídicí panel a správa
|
||||
|
||||
### Ověřování
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/auth/login` | ZVEŘEJNIT | Přihlášení
|
||||
`/api/auth/logout` | ZVEŘEJNIT | Odhlásit se
|
||||
`/api/settings/require-login` | ZÍSKAT/VLOŽIT | Vyžaduje se přepnutí přihlášení
|
||||
|
||||
### Správa poskytovatelů
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/providers` | ZÍSKAT/ODESLAT | Seznam / vytvoření poskytovatelů
|
||||
`/api/providers/[id]` | ZÍSKAT/VLOŽIT/ODSTRANIT | Správa poskytovatele
|
||||
`/api/providers/[id]/test` | ZVEŘEJNIT | Testovací připojení poskytovatele
|
||||
`/api/providers/[id]/models` | ZÍSKAT | Seznam modelů poskytovatelů
|
||||
`/api/providers/validate` | ZVEŘEJNIT | Ověření konfigurace poskytovatele
|
||||
`/api/provider-nodes*` | Různé | Správa uzlů poskytovatelů
|
||||
`/api/provider-models` | ZÍSKAT/ODESLAT/SMAZAT | Vlastní modely
|
||||
|
||||
### Toky OAuth
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/oauth/[provider]/[action]` | Různé | OAuth specifický pro poskytovatele
|
||||
|
||||
### Směrování a konfigurace
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/models/alias` | ZÍSKAT/ODESLAT | Aliasy modelů
|
||||
`/api/models/catalog` | ZÍSKAT | Všechny modely podle poskytovatele + typu
|
||||
`/api/combos*` | Různé | Správa kombinací
|
||||
`/api/keys*` | Různé | Správa klíčů API
|
||||
`/api/pricing` | ZÍSKAT | Cena modelu
|
||||
|
||||
### Využití a analýzy
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/usage/history` | ZÍSKAT | Historie používání
|
||||
`/api/usage/logs` | ZÍSKAT | Protokoly používání
|
||||
`/api/usage/request-logs` | ZÍSKAT | Protokoly na úrovni požadavků
|
||||
`/api/usage/[connectionId]` | ZÍSKAT | Využití na připojení
|
||||
|
||||
### Nastavení
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/settings` | ZÍSKAT/VLOŽIT | Obecná nastavení
|
||||
`/api/settings/proxy` | ZÍSKAT/VLOŽIT | Konfigurace síťového proxy serveru
|
||||
`/api/settings/proxy/test` | ZVEŘEJNIT | Testovací připojení k proxy serveru
|
||||
`/api/settings/ip-filter` | ZÍSKAT/VLOŽIT | Seznam povolených/blokovaných IP adres
|
||||
`/api/settings/thinking-budget` | ZÍSKAT/VLOŽIT | Zdůvodnění rozpočtu tokenů
|
||||
`/api/settings/system-prompt` | ZÍSKAT/VLOŽIT | Globální systémový výzva
|
||||
|
||||
### Monitorování
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/sessions` | ZÍSKAT | Sledování aktivních relací
|
||||
`/api/rate-limits` | ZÍSKAT | Limity sazeb na účet
|
||||
`/api/monitoring/health` | ZÍSKAT | Kontrola stavu
|
||||
`/api/cache` | ZÍSKAT/SMAZAT | Statistiky mezipaměti / vymazat
|
||||
|
||||
### Zálohování a export/import
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/db-backups` | ZÍSKAT | Seznam dostupných záloh
|
||||
`/api/db-backups` | DÁT | Vytvořte ruční zálohu
|
||||
`/api/db-backups` | ZVEŘEJNIT | Obnovení z konkrétní zálohy
|
||||
`/api/db-backups/export` | ZÍSKAT | Stáhnout databázi jako soubor .sqlite
|
||||
`/api/db-backups/import` | ZVEŘEJNIT | Nahrajte soubor .sqlite pro nahrazení databáze
|
||||
`/api/db-backups/exportAll` | ZÍSKAT | Stáhnout plnou zálohu jako archiv .tar.gz
|
||||
|
||||
### Synchronizace s cloudem
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/sync/cloud` | Různé | Operace synchronizace s cloudem
|
||||
`/api/sync/initialize` | ZVEŘEJNIT | Inicializovat synchronizaci
|
||||
`/api/cloud/*` | Různé | Správa cloudu
|
||||
|
||||
### Nástroje CLI
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/cli-tools/claude-settings` | ZÍSKAT | Stav Clauda CLI
|
||||
`/api/cli-tools/codex-settings` | ZÍSKAT | Stav příkazového řádku Codexu
|
||||
`/api/cli-tools/droid-settings` | ZÍSKAT | Stav příkazového řádku Droidu
|
||||
`/api/cli-tools/openclaw-settings` | ZÍSKAT | Stav rozhraní příkazového řádku OpenClaw
|
||||
`/api/cli-tools/runtime/[toolId]` | ZÍSKAT | Generické běhové prostředí CLI
|
||||
|
||||
Mezi odpovědi CLI patří: `installed` , `runnable` , `command` , `commandPath` , `runtimeMode` , `reason` .
|
||||
|
||||
### Agenti ACP
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/acp/agents` | ZÍSKAT | Zobrazit seznam všech detekovaných agentů (vestavěných + vlastních) se stavem
|
||||
`/api/acp/agents` | ZVEŘEJNIT | Přidat vlastního agenta nebo obnovit mezipaměť detekce
|
||||
`/api/acp/agents` | VYMAZAT | Odebrání vlastního agenta podle parametru dotazu `id`
|
||||
|
||||
Odpověď GET obsahuje `agents[]` (id, name, binary, version, installed, protocol, isCustom) a `summary` (total, installed, notFound, builtIn, custom).
|
||||
|
||||
### Odolnost a limity rychlosti
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/resilience` | ZÍSKAT/VLOŽIT | Získání/aktualizace profilů odolnosti
|
||||
`/api/resilience/reset` | ZVEŘEJNIT | Resetujte jističe
|
||||
`/api/rate-limits` | ZÍSKAT | Stav limitu sazby na účet
|
||||
`/api/rate-limit` | ZÍSKAT | Konfigurace globálního limitu rychlosti
|
||||
|
||||
### Evals
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/evals` | ZÍSKAT/ODESLAT | Vypsat eval sady / spustit vyhodnocení
|
||||
|
||||
### Zásady
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/policies` | ZÍSKAT/ODESLAT/SMAZAT | Správa směrovacích zásad
|
||||
|
||||
### Dodržování
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/compliance/audit-log` | ZÍSKAT | Protokol auditu shody (poslední N)
|
||||
|
||||
### v1beta (kompatibilní s Gemini)
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/v1beta/models` | ZÍSKAT | Seznam modelů ve formátu Gemini
|
||||
`/v1beta/models/{...path}` | ZVEŘEJNIT | Koncový bod Gemini `generateContent`
|
||||
|
||||
Tyto koncové body zrcadlí formát API Gemini pro klienty, kteří očekávají nativní kompatibilitu sady Gemini SDK.
|
||||
|
||||
### Interní / systémová API
|
||||
|
||||
Koncový bod | Metoda | Popis
|
||||
--- | --- | ---
|
||||
`/api/init` | ZÍSKAT | Kontrola inicializace aplikace (používá se při prvním spuštění)
|
||||
`/api/tags` | ZÍSKAT | Tagy modelů kompatibilní s Ollamou (pro klienty Ollamy)
|
||||
`/api/restart` | ZVEŘEJNIT | Spustit řádný restart serveru
|
||||
`/api/shutdown` | ZVEŘEJNIT | Spustit řádné vypnutí serveru
|
||||
|
||||
> **Poznámka:** Tyto koncové body používá interně systém nebo pro kompatibilitu s klienty Ollama. Koncoví uživatelé je obvykle nevolají.
|
||||
|
||||
---
|
||||
|
||||
## Přepis zvuku
|
||||
|
||||
```bash
|
||||
POST /v1/audio/transcriptions
|
||||
Authorization: Bearer your-api-key
|
||||
Content-Type: multipart/form-data
|
||||
```
|
||||
|
||||
Přepisujte zvukové soubory pomocí Deepgramu nebo AssemblyAI.
|
||||
|
||||
**Žá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"
|
||||
```
|
||||
|
||||
**Odpověď:**
|
||||
|
||||
```json
|
||||
{
|
||||
"text": "Hello, this is the transcribed audio content.",
|
||||
"task": "transcribe",
|
||||
"language": "en",
|
||||
"duration": 12.5
|
||||
}
|
||||
```
|
||||
|
||||
**Podporovaní poskytovatelé:** `deepgram/nova-3` , `assemblyai/best` .
|
||||
|
||||
**Podporované formáty:** `mp3` , `wav` , `m4a` , `flac` , `ogg` , `webm` .
|
||||
|
||||
---
|
||||
|
||||
## Kompatibilita s Ollamou
|
||||
|
||||
Pro klienty, kteří používají formát API od Ollamy:
|
||||
|
||||
```bash
|
||||
# Chat endpoint (Ollama format)
|
||||
POST /v1/api/chat
|
||||
|
||||
# Model listing (Ollama format)
|
||||
GET /api/tags
|
||||
```
|
||||
|
||||
Požadavky jsou automaticky překládány mezi formátem Ollama a interním formátem.
|
||||
|
||||
---
|
||||
|
||||
## Telemetrie
|
||||
|
||||
```bash
|
||||
# Get latency telemetry summary (p50/p95/p99 per provider)
|
||||
GET /api/telemetry/summary
|
||||
```
|
||||
|
||||
**Odpověď:**
|
||||
|
||||
```json
|
||||
{
|
||||
"providers": {
|
||||
"claudeCode": { "p50": 245, "p95": 890, "p99": 1200, "count": 150 },
|
||||
"github": { "p50": 180, "p95": 620, "p99": 950, "count": 320 }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Rozpočet
|
||||
|
||||
```bash
|
||||
# Get budget status for all API keys
|
||||
GET /api/usage/budget
|
||||
|
||||
# Set or update a budget
|
||||
POST /api/usage/budget
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"keyId": "key-123",
|
||||
"limit": 50.00,
|
||||
"period": "monthly"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Dostupnost modelu
|
||||
|
||||
```bash
|
||||
# Get real-time model availability across all providers
|
||||
GET /api/models/availability
|
||||
|
||||
# Check availability for a specific model
|
||||
POST /api/models/availability
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"model": "claude-sonnet-4-5-20250929"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Zpracování žádosti
|
||||
|
||||
1. Klient odesílá požadavek na `/v1/*`
|
||||
2. Obslužná rutina trasy volá `handleChat` , `handleEmbedding` , `handleAudioTranscription` nebo `handleImageGeneration`
|
||||
3. Model je vyřešen (přímý poskytovatel/model nebo alias/kombinace)
|
||||
4. Přihlašovací údaje vybrané z lokální databáze s filtrováním dostupnosti účtů
|
||||
5. Pro chat: `handleChatCore` — detekce formátu, překlad, kontrola mezipaměti, kontrola idempotence
|
||||
6. Prováděcí program poskytovatele odesílá požadavek nadřazenému serveru
|
||||
7. Odpověď přeložena zpět do klientského formátu (chat) nebo vrácena tak, jak je (vložené prvky/obrázky/zvuk)
|
||||
8. Zaznamenáno použití/protokolování
|
||||
9. Záložní metoda se použije na chyby podle pravidel kombinace.
|
||||
|
||||
Úplný referenční popis architektury: [`ARCHITECTURE.md`](ARCHITECTURE.md)
|
||||
|
||||
---
|
||||
|
||||
## Ověřování
|
||||
|
||||
- Trasy dashboardu ( `/dashboard/*` ) používají soubor cookie `auth_token`
|
||||
- Přihlášení používá uložený hash hesla; záložní nastavení je `INITIAL_PASSWORD`
|
||||
- `requireLogin` lze přepínat přes `/api/settings/require-login`
|
||||
- Trasy `/v1/*` volitelně vyžadují klíč API nosiče, pokud `REQUIRE_API_KEY=true`
|
||||
782
docs/i18n/cs/ARCHITECTURE.md
Normal file
782
docs/i18n/cs/ARCHITECTURE.md
Normal file
@@ -0,0 +1,782 @@
|
||||
# Architektura OmniRoute
|
||||
|
||||
🌐 **Jazyky:** 🇺🇸 [angličtina](ARCHITECTURE.md) | 🇧🇷 [Português (Brazílie)](i18n/pt-BR/ARCHITECTURE.md) | 🇪🇸 [Español](i18n/es/ARCHITECTURE.md) | 🇫🇷 [Français](i18n/fr/ARCHITECTURE.md) | 🇮🇹 [Italiano](i18n/it/ARCHITECTURE.md) | 🇷🇺 [Русский](i18n/ru/ARCHITECTURE.md) | 🇨🇳[中文 (简体)](i18n/zh-CN/ARCHITECTURE.md) | 🇩🇪 [Deutsch](i18n/de/ARCHITECTURE.md) | 🇮🇳 [हिन्दी](i18n/in/ARCHITECTURE.md) | 🇹🇭 [ไทย](i18n/th/ARCHITECTURE.md) | 🇺🇦 [Українська](i18n/uk-UA/ARCHITECTURE.md) | 🇸🇦 [العربية](i18n/ar/ARCHITECTURE.md) | 🇯🇵[日本語](i18n/ja/ARCHITECTURE.md)| 🇻🇳 [Tiếng Việt](i18n/vi/ARCHITECTURE.md) | 🇧🇬 [Български](i18n/bg/ARCHITECTURE.md) | 🇩🇰 [Dánsko](i18n/da/ARCHITECTURE.md) | 🇫🇮 [Suomi](i18n/fi/ARCHITECTURE.md) | 🇮🇱 [עברית](i18n/he/ARCHITECTURE.md) | 🇭🇺 [maďarština](i18n/hu/ARCHITECTURE.md) | 🇮🇩 [Bahasa Indonésie](i18n/id/ARCHITECTURE.md) | 🇰🇷 [한국어](i18n/ko/ARCHITECTURE.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/ARCHITECTURE.md) | 🇳🇱 [Nizozemsko](i18n/nl/ARCHITECTURE.md) | 🇳🇴 [Norsk](i18n/no/ARCHITECTURE.md) | 🇵🇹 [Português (Portugalsko)](i18n/pt/ARCHITECTURE.md) | 🇷🇴 [Română](i18n/ro/ARCHITECTURE.md) | 🇵🇱 [Polski](i18n/pl/ARCHITECTURE.md) | 🇸🇰 [Slovenčina](i18n/sk/ARCHITECTURE.md) | 🇸🇪 [Svenska](i18n/sv/ARCHITECTURE.md) | 🇵🇭 [Filipínec](i18n/phi/ARCHITECTURE.md) | 🇨🇿 [Čeština](i18n/cs/ARCHITECTURE.md)
|
||||
|
||||
*Poslední aktualizace: 2026-03-04*
|
||||
|
||||
## Shrnutí pro manažery
|
||||
|
||||
OmniRoute je lokální směrovací brána a dashboard s umělou inteligencí postavený na Next.js. Poskytuje jeden koncový bod kompatibilní s OpenAI ( `/v1/*` ) a směruje provoz napříč několika upstreamovými poskytovateli s překladem, záložními funkcemi, obnovou tokenů a sledováním využití.
|
||||
|
||||
Základní schopnosti:
|
||||
|
||||
- API prostředí kompatibilní s OpenAI pro CLI/nástroje (28 poskytovatelů)
|
||||
- Překlad požadavků/odpovědí napříč formáty poskytovatelů
|
||||
- Záložní kombinace modelů (sekvence s více modely)
|
||||
- Záložní řešení na úrovni účtu (více účtů na poskytovatele)
|
||||
- Správa připojení poskytovatele OAuth + API klíčů
|
||||
- Generování embeddingů pomocí `/v1/embeddings` (6 poskytovatelů, 9 modelů)
|
||||
- Generování obrázků pomocí `/v1/images/generations` (4 poskytovatelé, 9 modelů)
|
||||
- Pro modely uvažování zvažte analýzu tagů ( `<think>...</think>` ).
|
||||
- Sanitizace odpovědí pro striktní kompatibilitu s 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)
|
||||
- Lokální perzistence pro poskytovatele, klíče, aliasy, kombinace, nastavení, ceny
|
||||
- Sledování využití/nákladů a protokolování požadavků
|
||||
- Volitelná cloudová synchronizace pro synchronizaci více zařízení/stavů
|
||||
- Seznam povolených/blokovaných IP adres pro řízení přístupu k API
|
||||
- Řízení rozpočtu (průchozí/automatické/vlastní/adaptivní)
|
||||
- Globální systémová výzva k vložení
|
||||
- Sledování relací a otisky prstů
|
||||
- Vylepšené omezení sazeb pro jednotlivé účty s profily specifickými pro poskytovatele
|
||||
- Vzor jističů pro odolnost poskytovatele
|
||||
- Ochrana stáda proti hromům s uzamčením mutexů
|
||||
- Mezipaměť pro deduplikaci požadavků založená na podpisech
|
||||
- Vrstva domény: dostupnost modelu, pravidla nákladů, záložní politika, politika blokování
|
||||
- Perzistence stavu domény (mezipaměť SQLite pro zápis pro záložní funkce, rozpočty, uzamčení, jističe)
|
||||
- Modul zásad pro centralizované vyhodnocování požadavků (uzamčení → rozpočet → záložní)
|
||||
- Vyžádat telemetrii s agregací latence p50/p95/p99
|
||||
- Korelační ID (X-Request-Id) pro trasování typu end-to-end
|
||||
- Protokolování auditu shody s předpisy s možností odhlášení pro každý klíč API
|
||||
- Evaluační rámec pro zajištění kvality LLM
|
||||
- Řídicí panel uživatelského rozhraní Resilience se stavem jističe v reálném čase
|
||||
- Modulární poskytovatelé OAuth (12 jednotlivých modulů v adresáři `src/lib/oauth/providers/` )
|
||||
|
||||
Primární běhový model:
|
||||
|
||||
- Trasy aplikace Next.js v `src/app/api/*` implementují jak API dashboardů, tak i API kompatibility.
|
||||
- Sdílené jádro SSE/routing v `src/sse/*` + `open-sse/*` zvládá spouštění poskytovatelů, překlad, streamování, záložní operace a využití.
|
||||
|
||||
## Rozsah a hranice
|
||||
|
||||
### V rozsahu
|
||||
|
||||
- Běhové prostředí lokální brány
|
||||
- Rozhraní API pro správu řídicích panelů
|
||||
- Ověřování poskytovatele a aktualizace tokenu
|
||||
- Žádost o překlad a streamování SSE
|
||||
- Lokální stav + perzistence využití
|
||||
- Volitelná orchestrace synchronizace s cloudem
|
||||
|
||||
### Mimo rozsah
|
||||
|
||||
- Implementace cloudové služby za `NEXT_PUBLIC_CLOUD_URL`
|
||||
- SLA/řídicí rovina poskytovatele mimo lokální proces
|
||||
- Samotné externí binární soubory CLI (Claude CLI, Codex CLI atd.)
|
||||
|
||||
## Kontext systému na vysoké úrovni
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph Clients[Developer Clients]
|
||||
C1[Claude Code]
|
||||
C2[Codex CLI]
|
||||
C3[OpenClaw / Droid / Cline / Continue / Roo]
|
||||
C4[Custom OpenAI-compatible clients]
|
||||
BROWSER[Browser Dashboard]
|
||||
end
|
||||
|
||||
subgraph Router[OmniRoute Local Process]
|
||||
API[V1 Compatibility API\n/v1/*]
|
||||
DASH[Dashboard + Management API\n/api/*]
|
||||
CORE[SSE + Translation Core\nopen-sse + src/sse]
|
||||
DB[(storage.sqlite)]
|
||||
UDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph Upstreams[Upstream Providers]
|
||||
P1[OAuth Providers\nClaude/Codex/Gemini/Qwen/iFlow/GitHub/Kiro/Cursor/Antigravity]
|
||||
P2[API Key Providers\nOpenAI/Anthropic/OpenRouter/GLM/Kimi/MiniMax\nDeepSeek/Groq/xAI/Mistral/Perplexity\nTogether/Fireworks/Cerebras/Cohere/NVIDIA]
|
||||
P3[Compatible Nodes\nOpenAI-compatible / Anthropic-compatible]
|
||||
end
|
||||
|
||||
subgraph Cloud[Optional Cloud Sync]
|
||||
CLOUD[Cloud Sync Endpoint\nNEXT_PUBLIC_CLOUD_URL]
|
||||
end
|
||||
|
||||
C1 --> API
|
||||
C2 --> API
|
||||
C3 --> API
|
||||
C4 --> API
|
||||
BROWSER --> DASH
|
||||
|
||||
API --> CORE
|
||||
DASH --> DB
|
||||
CORE --> DB
|
||||
CORE --> UDB
|
||||
|
||||
CORE --> P1
|
||||
CORE --> P2
|
||||
CORE --> P3
|
||||
|
||||
DASH --> CLOUD
|
||||
```
|
||||
|
||||
## Základní běhové komponenty
|
||||
|
||||
## 1) API a směrovací vrstva (trasy aplikací Next.js)
|
||||
|
||||
Hlavní adresáře:
|
||||
|
||||
- `src/app/api/v1/*` a `src/app/api/v1beta/*` pro rozhraní API pro zajištění kompatibility
|
||||
- `src/app/api/*` pro API pro správu/konfiguraci
|
||||
- Další přepisy v `next.config.mjs` mapují `/v1/*` na `/api/v1/*`
|
||||
|
||||
Důležité způsoby 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` — obsahuje vlastní modely s `custom: true`
|
||||
- `src/app/api/v1/embeddings/route.ts` — generování embeddingů (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` — vyhrazený chat pro jednotlivé poskytovatele
|
||||
- `src/app/api/v1/providers/[provider]/embeddings/route.ts` — vyhrazená vkládání pro jednotlivé poskytovatele
|
||||
- `src/app/api/v1/providers/[provider]/images/generations/route.ts` — vyhrazené obrazy pro jednotlivé poskytovatele
|
||||
- `src/app/api/v1beta/models/route.ts`
|
||||
- `src/app/api/v1beta/models/[...path]/route.ts`
|
||||
|
||||
Domény správy:
|
||||
|
||||
- Auth/settings: `src/app/api/auth/*` , `src/app/api/settings/*`
|
||||
- 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/*`
|
||||
- Klíče/aliasy/kombinace/ceny: `src/app/api/keys*` , `src/app/api/models/alias` , `src/app/api/combos*` , `src/app/api/pricing`
|
||||
- Použití: `src/app/api/usage/*`
|
||||
- Synchronizace/cloud: `src/app/api/sync/*` , `src/app/api/cloud/*`
|
||||
- Pomocné nástroje pro CLI: `src/app/api/cli-tools/*`
|
||||
- IP filtr: `src/app/api/settings/ip-filter` (GET/PUT)
|
||||
- Rozpočet pro myšlení: `src/app/api/settings/thinking-budget` (GET/PUT)
|
||||
- Systémový příkaz: `src/app/api/settings/system-prompt` (GET/PUT)
|
||||
- Relace: `src/app/api/sessions` (GET)
|
||||
- Limity rychlosti: `src/app/api/rate-limits` (GET)
|
||||
- Odolnost: `src/app/api/resilience` (GET/PATCH) — profily poskytovatelů, jistič, stav limitu rychlosti
|
||||
- Reset odolnosti: `src/app/api/resilience/reset` (POST) — reset jističů + doby zchlazení
|
||||
- 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 shody: `src/app/api/compliance/audit-log` (GET)
|
||||
- Evals: `src/app/api/evals` (GET/POST), `src/app/api/evals/[suiteId]` (GET)
|
||||
- Zásady: `src/app/api/policies` (GET/POST)
|
||||
|
||||
## 2) SSE + Překladatelské jádro
|
||||
|
||||
Hlavní moduly toku:
|
||||
|
||||
- Záznam: `src/sse/handlers/chat.ts`
|
||||
- Orchestrace jádra: `open-sse/handlers/chatCore.ts`
|
||||
- Adaptéry pro spuštění poskytovatelů: `open-sse/executors/*`
|
||||
- Detekce formátu/konfigurace poskytovatele: `open-sse/services/provider.ts`
|
||||
- Analýza/řešení 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 streamů: `open-sse/utils/stream.ts` , `open-sse/utils/streamHandler.ts`
|
||||
- Extrakce/normalizace využití: `open-sse/utils/usageTracking.ts`
|
||||
- Analyzátor tagů Think: `open-sse/utils/thinkTagParser.ts`
|
||||
- Obslužná rutina pro vkládání: `open-sse/handlers/embeddings.ts`
|
||||
- Registr poskytovatelů vkládání: `open-sse/config/embeddingRegistry.ts`
|
||||
- Obslužná rutina generování obrázků: `open-sse/handlers/imageGeneration.ts`
|
||||
- Registr poskytovatelů obrázků: `open-sse/config/imageRegistry.ts`
|
||||
- Sanitizace odpovědí: `open-sse/handlers/responseSanitizer.ts`
|
||||
- Normalizace rolí: `open-sse/services/roleNormalizer.ts`
|
||||
|
||||
Služby (obchodní logika):
|
||||
|
||||
- Výběr/skórování účtu: `open-sse/services/accountSelector.ts`
|
||||
- Správa životního cyklu kontextu: `open-sse/services/contextManager.ts`
|
||||
- Vynucení filtrování IP adres: `open-sse/services/ipFilter.ts`
|
||||
- Sledování relací: `open-sse/services/sessionManager.ts`
|
||||
- Požadavek na deduplikaci: `open-sse/services/signatureCache.ts`
|
||||
- Vložení systémového promptu: `open-sse/services/systemPrompt.ts`
|
||||
- Řízení rozpočtu v duchu myšlenek: `open-sse/services/thinkingBudget.ts`
|
||||
- Směrování pomocí modelu zástupných znaků: `open-sse/services/wildcardRouter.ts`
|
||||
- Správa limitů rychlosti: `open-sse/services/rateLimitManager.ts`
|
||||
- Jistič: `open-sse/services/circuitBreaker.ts`
|
||||
|
||||
Moduly doménové vrstvy:
|
||||
|
||||
- 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`
|
||||
- Kombinovaný resolver: `src/lib/domain/comboResolver.ts`
|
||||
- Zásady uzamčení: `src/lib/domain/lockoutPolicy.ts`
|
||||
- Modul zásad: `src/domain/policyEngine.ts` — centralizované uzamčení → rozpočet → vyhodnocení záložního režimu
|
||||
- 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`
|
||||
- Požadovat telemetrii: `src/lib/domain/requestTelemetry.ts`
|
||||
- Shoda/audit: `src/lib/domain/compliance/index.ts`
|
||||
- Zkušební běžec: `src/lib/domain/evalRunner.ts`
|
||||
- Perzistence 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
|
||||
|
||||
Moduly poskytovatelů OAuth (12 jednotlivých souborů v adresáři `src/lib/oauth/providers/` ):
|
||||
|
||||
- Index registru: `src/lib/oauth/providers/index.ts`
|
||||
- Jednotliví poskytovatelé: `claude.ts` , `codex.ts` , `gemini.ts` , `antigravity.ts` , `iflow.ts` , `qwen.ts` , `kimi-coding.ts` , `github.ts` , `kiro.ts` , `cursor.ts` , `kilocode.ts` , `cline.ts`
|
||||
- Thin wrapper: `src/lib/oauth/providers.ts` — reexporty z jednotlivých modulů
|
||||
|
||||
## 3) Vrstva perzistence
|
||||
|
||||
Primární stavová databáze (SQLite):
|
||||
|
||||
- Základní infrastruktura: `src/lib/db/core.ts` (better-sqlite3, migrace, WAL)
|
||||
- Reexportní fasáda: `src/lib/localDb.ts` (tenká vrstva kompatibility pro volající)
|
||||
- soubor: `${DATA_DIR}/storage.sqlite` (nebo `$XDG_CONFIG_HOME/omniroute/storage.sqlite` pokud je nastaveno, jinak `~/.omniroute/storage.sqlite` )
|
||||
- entity (tabulky + jmenné prostory KV): providerConnections, providerNodes, modelAliases, combos, apiKeys, settings, pricing, **customModels** , **proxyConfig** , **ipFilter** , **thinkingBudget** , **systemPrompt**
|
||||
|
||||
Trvalost používání:
|
||||
|
||||
- fasáda: `src/lib/usageDb.ts` (dekomponované moduly v `src/lib/usage/*` )
|
||||
- SQLite tabulky v `storage.sqlite` : `usage_history` , `call_logs` , `proxy_logs`
|
||||
- Volitelné artefakty souborů zůstávají pro účely kompatibility/ladění ( `${DATA_DIR}/log.txt` , `${DATA_DIR}/call_logs/` , `<repo>/logs/...` )
|
||||
- Starší soubory JSON jsou migrovány do SQLite při migracích při spuštění, pokud jsou k dispozici.
|
||||
|
||||
Databáze stavu domény (SQLite):
|
||||
|
||||
- `src/lib/db/domainState.ts` — CRUD operace 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 se obnovuje z databáze při studeném startu.
|
||||
|
||||
## 4) Ověřovací a bezpečnostní povrchy
|
||||
|
||||
- Autorizace souborů cookie v dashboardu: `src/proxy.ts` , `src/app/api/auth/login/route.ts`
|
||||
- Generování/ověření klíče API: `src/shared/utils/apiKey.ts`
|
||||
- Tajné kódy poskytovatele přetrvávaly v položkách `providerConnections`
|
||||
- Podpora odchozí proxy přes `open-sse/utils/proxyFetch.ts` (proměnné prostředí) a `open-sse/utils/networkProxy.ts` (konfigurovatelné pro jednotlivé poskytovatele nebo globálně)
|
||||
|
||||
## 5) Synchronizace s cloudem
|
||||
|
||||
- Inicializace plánovače: `src/lib/initCloudSync.ts` , `src/shared/services/initializeCloudSync.ts`
|
||||
- Periodická úloha: `src/shared/services/cloudSyncScheduler.ts`
|
||||
- Řídicí trasa: `src/app/api/sync/cloud/route.ts`
|
||||
|
||||
## Životní cyklus požadavku ( `/v1/chat/completions` )
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant Client as CLI/SDK Client
|
||||
participant Route as /api/v1/chat/completions
|
||||
participant Chat as src/sse/handlers/chat
|
||||
participant Core as open-sse/handlers/chatCore
|
||||
participant Model as Model Resolver
|
||||
participant Auth as Credential Selector
|
||||
participant Exec as Provider Executor
|
||||
participant Prov as Upstream Provider
|
||||
participant Stream as Stream Translator
|
||||
participant Usage as usageDb
|
||||
|
||||
Client->>Route: POST /v1/chat/completions
|
||||
Route->>Chat: handleChat(request)
|
||||
Chat->>Model: parse/resolve model or combo
|
||||
|
||||
alt Combo model
|
||||
Chat->>Chat: iterate combo models (handleComboChat)
|
||||
end
|
||||
|
||||
Chat->>Auth: getProviderCredentials(provider)
|
||||
Auth-->>Chat: active account + tokens/api key
|
||||
|
||||
Chat->>Core: handleChatCore(body, modelInfo, credentials)
|
||||
Core->>Core: detect source format
|
||||
Core->>Core: translate request to target format
|
||||
Core->>Exec: execute(provider, transformedBody)
|
||||
Exec->>Prov: upstream API call
|
||||
Prov-->>Exec: SSE/JSON response
|
||||
Exec-->>Core: response + metadata
|
||||
|
||||
alt 401/403
|
||||
Core->>Exec: refreshCredentials()
|
||||
Exec-->>Core: updated tokens
|
||||
Core->>Exec: retry request
|
||||
end
|
||||
|
||||
Core->>Stream: translate/normalize stream to client format
|
||||
Stream-->>Client: SSE chunks / JSON response
|
||||
|
||||
Stream->>Usage: extract usage + persist history/log
|
||||
```
|
||||
|
||||
## Kombinovaný + záložní proces pro účet
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Incoming model string] --> B{Is combo name?}
|
||||
B -- Yes --> C[Load combo models sequence]
|
||||
B -- No --> D[Single model path]
|
||||
|
||||
C --> E[Try model N]
|
||||
E --> F[Resolve provider/model]
|
||||
D --> F
|
||||
|
||||
F --> G[Select account credentials]
|
||||
G --> H{Credentials available?}
|
||||
H -- No --> I[Return provider unavailable]
|
||||
H -- Yes --> J[Execute request]
|
||||
|
||||
J --> K{Success?}
|
||||
K -- Yes --> L[Return response]
|
||||
K -- No --> M{Fallback-eligible error?}
|
||||
|
||||
M -- No --> N[Return error]
|
||||
M -- Yes --> O[Mark account unavailable cooldown]
|
||||
O --> P{Another account for provider?}
|
||||
P -- Yes --> G
|
||||
P -- No --> Q{In combo with next model?}
|
||||
Q -- Yes --> E
|
||||
Q -- No --> R[Return all unavailable]
|
||||
```
|
||||
|
||||
Rozhodnutí o záložních metodách jsou řízena souborem `open-sse/services/accountFallback.ts` s využitím stavových kódů a heuristik chybových zpráv.
|
||||
|
||||
## Životní cyklus aktualizace OAuth a onboardingu tokenu
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Dashboard UI
|
||||
participant OAuth as /api/oauth/[provider]/[action]
|
||||
participant ProvAuth as Provider Auth Server
|
||||
participant DB as localDb
|
||||
participant Test as /api/providers/[id]/test
|
||||
participant Exec as Provider Executor
|
||||
|
||||
UI->>OAuth: GET authorize or device-code
|
||||
OAuth->>ProvAuth: create auth/device flow
|
||||
ProvAuth-->>OAuth: auth URL or device code payload
|
||||
OAuth-->>UI: flow data
|
||||
|
||||
UI->>OAuth: POST exchange or poll
|
||||
OAuth->>ProvAuth: token exchange/poll
|
||||
ProvAuth-->>OAuth: access/refresh tokens
|
||||
OAuth->>DB: createProviderConnection(oauth data)
|
||||
OAuth-->>UI: success + connection id
|
||||
|
||||
UI->>Test: POST /api/providers/[id]/test
|
||||
Test->>Exec: validate credentials / optional refresh
|
||||
Exec-->>Test: valid or refreshed token info
|
||||
Test->>DB: update status/tokens/errors
|
||||
Test-->>UI: validation result
|
||||
```
|
||||
|
||||
Obnovení během živého provozu se provádí uvnitř `open-sse/handlers/chatCore.ts` pomocí exekutoru `refreshCredentials()` .
|
||||
|
||||
## Životní cyklus synchronizace s cloudem (Povolit / Synchronizovat / Zakázat)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
autonumber
|
||||
participant UI as Endpoint Page UI
|
||||
participant Sync as /api/sync/cloud
|
||||
participant DB as localDb
|
||||
participant Cloud as External Cloud Sync
|
||||
participant Claude as ~/.claude/settings.json
|
||||
|
||||
UI->>Sync: POST action=enable
|
||||
Sync->>DB: set cloudEnabled=true
|
||||
Sync->>DB: ensure API key exists
|
||||
Sync->>Cloud: POST /sync/{machineId} (providers/aliases/combos/keys)
|
||||
Cloud-->>Sync: sync result
|
||||
Sync->>Cloud: GET /{machineId}/v1/verify
|
||||
Sync-->>UI: enabled + verification status
|
||||
|
||||
UI->>Sync: POST action=sync
|
||||
Sync->>Cloud: POST /sync/{machineId}
|
||||
Cloud-->>Sync: remote data
|
||||
Sync->>DB: update newer local tokens/status
|
||||
Sync-->>UI: synced
|
||||
|
||||
UI->>Sync: POST action=disable
|
||||
Sync->>DB: set cloudEnabled=false
|
||||
Sync->>Cloud: DELETE /sync/{machineId}
|
||||
Sync->>Claude: switch ANTHROPIC_BASE_URL back to local (if needed)
|
||||
Sync-->>UI: disabled
|
||||
```
|
||||
|
||||
Pravidelnou synchronizaci spouští `CloudSyncScheduler` , když je povolen cloud.
|
||||
|
||||
## Datový model a mapa úložiště
|
||||
|
||||
```mermaid
|
||||
erDiagram
|
||||
SETTINGS ||--o{ PROVIDER_CONNECTION : controls
|
||||
PROVIDER_NODE ||--o{ PROVIDER_CONNECTION : backs_compatible_provider
|
||||
PROVIDER_CONNECTION ||--o{ USAGE_ENTRY : emits_usage
|
||||
|
||||
SETTINGS {
|
||||
boolean cloudEnabled
|
||||
number stickyRoundRobinLimit
|
||||
boolean requireLogin
|
||||
string password_hash
|
||||
string fallbackStrategy
|
||||
json rateLimitDefaults
|
||||
json providerProfiles
|
||||
}
|
||||
|
||||
PROVIDER_CONNECTION {
|
||||
string id
|
||||
string provider
|
||||
string authType
|
||||
string name
|
||||
number priority
|
||||
boolean isActive
|
||||
string apiKey
|
||||
string accessToken
|
||||
string refreshToken
|
||||
string expiresAt
|
||||
string testStatus
|
||||
string lastError
|
||||
string rateLimitedUntil
|
||||
json providerSpecificData
|
||||
}
|
||||
|
||||
PROVIDER_NODE {
|
||||
string id
|
||||
string type
|
||||
string name
|
||||
string prefix
|
||||
string apiType
|
||||
string baseUrl
|
||||
}
|
||||
|
||||
MODEL_ALIAS {
|
||||
string alias
|
||||
string targetModel
|
||||
}
|
||||
|
||||
COMBO {
|
||||
string id
|
||||
string name
|
||||
string[] models
|
||||
}
|
||||
|
||||
API_KEY {
|
||||
string id
|
||||
string name
|
||||
string key
|
||||
string machineId
|
||||
}
|
||||
|
||||
USAGE_ENTRY {
|
||||
string provider
|
||||
string model
|
||||
number prompt_tokens
|
||||
number completion_tokens
|
||||
string connectionId
|
||||
string timestamp
|
||||
}
|
||||
|
||||
CUSTOM_MODEL {
|
||||
string id
|
||||
string name
|
||||
string providerId
|
||||
}
|
||||
|
||||
PROXY_CONFIG {
|
||||
string global
|
||||
json providers
|
||||
}
|
||||
|
||||
IP_FILTER {
|
||||
string mode
|
||||
string[] allowlist
|
||||
string[] blocklist
|
||||
}
|
||||
|
||||
THINKING_BUDGET {
|
||||
string mode
|
||||
number customBudget
|
||||
string effortLevel
|
||||
}
|
||||
|
||||
SYSTEM_PROMPT {
|
||||
boolean enabled
|
||||
string prompt
|
||||
string position
|
||||
}
|
||||
```
|
||||
|
||||
Soubory fyzického úložiště:
|
||||
|
||||
- primární běhová databáze: `${DATA_DIR}/storage.sqlite`
|
||||
- řádky protokolu požadavku: `${DATA_DIR}/log.txt` (artefakt kompatibility/ladění)
|
||||
- Archivy strukturovaných dat volání: `${DATA_DIR}/call_logs/`
|
||||
- volitelné relace překladače/vyžádání ladění: `<repo>/logs/...`
|
||||
|
||||
## Topologie nasazení
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
subgraph LocalHost[Developer Host]
|
||||
CLI[CLI Tools]
|
||||
Browser[Dashboard Browser]
|
||||
end
|
||||
|
||||
subgraph ContainerOrProcess[OmniRoute Runtime]
|
||||
Next[Next.js Server\nPORT=20128]
|
||||
Core[SSE Core + Executors]
|
||||
MainDB[(storage.sqlite)]
|
||||
UsageDB[(usage tables + log artifacts)]
|
||||
end
|
||||
|
||||
subgraph External[External Services]
|
||||
Providers[AI Providers]
|
||||
SyncCloud[Cloud Sync Service]
|
||||
end
|
||||
|
||||
CLI --> Next
|
||||
Browser --> Next
|
||||
Next --> Core
|
||||
Next --> MainDB
|
||||
Core --> MainDB
|
||||
Core --> UsageDB
|
||||
Core --> Providers
|
||||
Next --> SyncCloud
|
||||
```
|
||||
|
||||
## Mapování modulů (kritické pro rozhodnutí)
|
||||
|
||||
### Moduly tras a API
|
||||
|
||||
- `src/app/api/v1/*` , `src/app/api/v1beta/*` : API pro zajištění kompatibility
|
||||
- `src/app/api/v1/providers/[provider]/*` : vyhrazené trasy pro jednotlivé poskytovatele (chat, vkládání, obrázky)
|
||||
- `src/app/api/providers*` : CRUD poskytovatele, validace, testování
|
||||
- `src/app/api/provider-nodes*` : správa uzlů kompatibilních s vlastními nástroji
|
||||
- `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 lokální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řepsání cen pro výpočet nákladů
|
||||
- `src/app/api/settings/proxy` : konfigurace proxy (GET/PUT/DELETE)
|
||||
- `src/app/api/settings/proxy/test` : test připojení odchozí proxy (POST)
|
||||
- `src/app/api/usage/*` : API pro použití a protokoly
|
||||
- `src/app/api/sync/*` + `src/app/api/cloud/*` : synchronizace s cloudem a pomocníci pro práci s cloudem
|
||||
- `src/app/api/cli-tools/*` : lokální programy pro zápis/kontrolu 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 thinking (GET/PUT)
|
||||
- `src/app/api/settings/system-prompt` : globální systémový příkaz (GET/PUT)
|
||||
- `src/app/api/sessions` : výpis aktivních relací (GET)
|
||||
- `src/app/api/rate-limits` : stav limitu rychlosti pro účet (GET)
|
||||
|
||||
### Směrovací a spouštěcí jádro
|
||||
|
||||
- `src/sse/handlers/chat.ts` : parsování požadavků, zpracování kombinací, smyčka výběru účtu
|
||||
- `open-sse/handlers/chatCore.ts` : překlad, odeslání exekutoru, zpracování opakování/obnovení, nastavení streamu
|
||||
- `open-sse/executors/*` : chování sítě a formátu specifické pro poskytovatele
|
||||
|
||||
### Registr překladů a převodníky formátů
|
||||
|
||||
- `open-sse/translator/index.ts` : registr a orchestrace překladačů
|
||||
- Žádost o překladatele: `open-sse/translator/request/*`
|
||||
- Překladače odpovědí: `open-sse/translator/response/*`
|
||||
- Formátovací konstanty: `open-sse/translator/formats.ts`
|
||||
|
||||
### Perzistence
|
||||
|
||||
- `src/lib/db/*` : perzistentní ukládání konfigurace/stavu a domény v SQLite
|
||||
- `src/lib/localDb.ts` : reexport kompatibility pro databázové moduly
|
||||
- `src/lib/usageDb.ts` : fasáda historie použití/záznamů volání nad tabulkami SQLite
|
||||
|
||||
## Pokrytí poskytovatele a vykonavatele (strategický vzorec)
|
||||
|
||||
Každý poskytovatel má specializovaný exekutor rozšiřující `BaseExecutor` (v `open-sse/executors/base.ts` ), který zajišťuje vytváření URL adres, konstrukci hlaviček, opakování s exponenciálním odkladem, hooky pro obnovení pověření a orchestrační metodu `execute()` .
|
||||
|
||||
Vykonavatel | Poskytovatel(é) | Speciální manipulace
|
||||
--- | --- | ---
|
||||
`DefaultExecutor` | OpenAI, Claude, Gemini, Qwen, iFlow, OpenRouter, GLM, Kimi, MiniMax, DeepSeek, Groq, xAI, Mistral, Perplexity, Together, Fireworks, Cerebras, Cohere, NVIDIA | Konfigurace dynamické adresy URL/záhlaví pro každého poskytovatele
|
||||
`AntigravityExecutor` | Google Antigravitace | Vlastní ID projektů/relací, analýza Opakování po
|
||||
`CodexExecutor` | Kodex OpenAI | Vkládá systémové instrukce, vynucuje úsilí k uvažování
|
||||
`CursorExecutor` | IDE kurzoru | Protokol ConnectRPC, kódování Protobuf, podepisování požadavků pomocí kontrolního součtu
|
||||
`GithubExecutor` | GitHub Copilot | Aktualizace tokenu Copilot, hlavičky napodobující VSCode
|
||||
`KiroExecutor` | AWS CodeWhisperer/Kiro | Binární formát AWS EventStream → konverze SSE
|
||||
`GeminiCLIExecutor` | Rozhraní příkazového řádku Gemini | Cyklus obnovy tokenu Google OAuth
|
||||
|
||||
Všichni ostatní poskytovatelé (včetně uzlů kompatibilních s vlastními funkcemi) používají `DefaultExecutor` .
|
||||
|
||||
## Matice kompatibility poskytovatelů
|
||||
|
||||
Poskytovatel | Formát | Autorizace | Proud | Nestreamované | Obnovení tokenu | API pro použití
|
||||
--- | --- | --- | --- | --- | --- | ---
|
||||
Claude | Claude | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Pouze pro administrátory
|
||||
Blíženci | Blíženci | Klíč API / OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole
|
||||
Rozhraní příkazového řádku Gemini | gemini-cli | OAuth | ✅ | ✅ | ✅ | ⚠️ Cloudová konzole
|
||||
Antigravitace | antigravitace | OAuth | ✅ | ✅ | ✅ | ✅ Plná kvóta API
|
||||
OpenAI | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Kodex | openai-odpovědi | OAuth | ✅ vynucený | ❌ | ✅ | ✅ Limity sazeb
|
||||
GitHub Copilot | otevřeno | OAuth + token Copilota | ✅ | ✅ | ✅ | ✅ Snímky kvót
|
||||
Kurzor | kurzor | Vlastní kontrolní součet | ✅ | ✅ | ❌ | ❌
|
||||
Kiro | Kiro | OIDC pro jednotné přihlašování AWS | ✅ (Stream událostí) | ❌ | ✅ | ✅ Limity použití
|
||||
Qwen | otevřeno | OAuth | ✅ | ✅ | ✅ | ⚠️ Na vyžádání
|
||||
iFlow | otevřeno | OAuth (základní) | ✅ | ✅ | ✅ | ⚠️ Na vyžádání
|
||||
OpenRouter | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
GLM/Kimi/MiniMax | Claude | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Hluboké vyhledávání | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Groq | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
xAI (Grok) | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Mistral | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Zmatek | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Společně s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Ohňostroj s umělou inteligencí | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Mozky | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
Soudržný | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
NVIDIA NIM | otevřeno | Klíč API | ✅ | ✅ | ❌ | ❌
|
||||
|
||||
## Pokrytí překladů formátů
|
||||
|
||||
Mezi detekované zdrojové formáty patří:
|
||||
|
||||
- `openai`
|
||||
- `openai-responses`
|
||||
- `claude`
|
||||
- `gemini`
|
||||
|
||||
Cílové formáty zahrnují:
|
||||
|
||||
- Chat/Odpovědi v OpenAI
|
||||
- Claude
|
||||
- Obálka Gemini/Gemini-CLI/Antigravitace
|
||||
- Kiro
|
||||
- Kurzor
|
||||
|
||||
Překlady používají **jako ústřední formát OpenAI** – všechny konverze procházejí OpenAI jako zprostředkovatel:
|
||||
|
||||
```
|
||||
Source Format → OpenAI (hub) → Target Format
|
||||
```
|
||||
|
||||
Překlady jsou vybírány dynamicky na základě tvaru zdrojového datového obsahu a formátu cílového poskytovatele.
|
||||
|
||||
Další vrstvy zpracování v překladovém kanálu:
|
||||
|
||||
- **Sanitizace odpovědí** – 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 SDK.
|
||||
- **Normalizace rolí** — Převádí `developer` → `system` pro cíle mimo OpenAI; slučuje `system` → `user` pro modely, které odmítají systémovou roli (GLM, ERNIE)
|
||||
- **Extrakce tagu Think** — Analyzuje bloky `<think>...</think>` z obsahu do pole `reasoning_content`
|
||||
- **Strukturovaný výstup** — Převede OpenAI `response_format.json_schema` na `responseMimeType` + `responseSchema` z Gemini.
|
||||
|
||||
## Podporované koncové body API
|
||||
|
||||
Koncový bod | Formát | Psovod
|
||||
--- | --- | ---
|
||||
`POST /v1/chat/completions` | Chat s OpenAI | `src/sse/handlers/chat.ts`
|
||||
`POST /v1/messages` | Claude Messages | Stejný obslužný program (automaticky detekováno)
|
||||
`POST /v1/responses` | Reakce OpenAI | `open-sse/handlers/responsesHandler.ts`
|
||||
`POST /v1/embeddings` | Vkládání OpenAI | `open-sse/handlers/embeddings.ts`
|
||||
`GET /v1/embeddings` | Seznam modelů | Trasa API
|
||||
`POST /v1/images/generations` | Obrázky OpenAI | `open-sse/handlers/imageGeneration.ts`
|
||||
`GET /v1/images/generations` | Seznam modelů | Trasa API
|
||||
`POST /v1/providers/{provider}/chat/completions` | Chat s OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
|
||||
`POST /v1/providers/{provider}/embeddings` | Vkládání OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
|
||||
`POST /v1/providers/{provider}/images/generations` | Obrázky OpenAI | Vyhrazené pro každého poskytovatele s ověřováním modelu
|
||||
`POST /v1/messages/count_tokens` | Počet žetonů Claude | Trasa API
|
||||
`GET /v1/models` | Seznam modelů OpenAI | Trasa API (chat + vkládání + obrázek + vlastní modely)
|
||||
`GET /api/models/catalog` | Katalog | Všechny modely seskupené podle poskytovatele + typu
|
||||
`POST /v1beta/models/*:streamGenerateContent` | Rodák z Blíženců | Trasa API
|
||||
`GET/PUT/DELETE /api/settings/proxy` | Konfigurace proxy serveru | Konfigurace síťového proxy serveru
|
||||
`POST /api/settings/proxy/test` | Připojení proxy serveru | Koncový bod testu stavu/připojení proxy serveru
|
||||
`GET/POST/DELETE /api/provider-models` | Vlastní modely | Správa vlastních modelů pro každého poskytovatele
|
||||
|
||||
## Obejít obslužnou rutinu
|
||||
|
||||
Obslužná rutina bypassu ( `open-sse/utils/bypassHandler.ts` ) zachycuje známé „throwaway“ požadavky z Claude CLI – warmup pingy, extrakce titulků a počty tokenů – a vrací **falešnou odpověď** bez spotřebování tokenů upstreamového poskytovatele. Toto se spustí pouze tehdy, když `User-Agent` obsahuje `claude-cli` .
|
||||
|
||||
## Kanál protokolování požadavků
|
||||
|
||||
Záznamník požadavků ( `open-sse/utils/requestLogger.ts` ) poskytuje 7stupňový kanál protokolování ladění, ve výchozím nastavení zakázaný a 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
|
||||
```
|
||||
|
||||
Soubory se zapisují do `<repo>/logs/<session>/` pro každou relaci požadavku.
|
||||
|
||||
## Způsoby selhání a odolnost
|
||||
|
||||
## 1) Dostupnost účtu/poskytovatele
|
||||
|
||||
- Doba ochlazování účtu poskytovatele při přechodných chybách/chybách rychlosti/autentizace
|
||||
- záložní účet před selháním požadavku
|
||||
- záložní kombinovaný model, když je aktuální cesta modelu/poskytovatele vyčerpána
|
||||
|
||||
## 2) Platnost tokenu
|
||||
|
||||
- předběžná kontrola a obnovení s opakovaným pokusem o obnovení poskytovatelů
|
||||
- Opakování 401/403 po pokusu o obnovení v hlavní cestě
|
||||
|
||||
## 3) Bezpečnost streamu
|
||||
|
||||
- streamovací řadič 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) Zhoršení cloudové synchronizace
|
||||
|
||||
- Zobrazují se chyby synchronizace, ale lokální běhové prostředí pokračuje.
|
||||
- Plánovač má logiku umožňující opakování, ale periodické provádění v současné době ve výchozím nastavení volá synchronizaci s jedním pokusem.
|
||||
|
||||
## 5) Integrita dat
|
||||
|
||||
- Migrace schématu SQLite a automatické aktualizace hooků při spuštění
|
||||
- Cesta kompatibility migrace starší verze JSON → SQLite
|
||||
|
||||
## Pozorovatelnost a provozní signály
|
||||
|
||||
Zdroje viditelnosti za běhu:
|
||||
|
||||
- protokoly konzole ze `src/sse/utils/logger.ts`
|
||||
- Agregace využití na požadavek v SQLite ( `usage_history` , `call_logs` , `proxy_logs` )
|
||||
- textový stav požadavku přihlášení `log.txt` (volitelné/kompatibilní)
|
||||
- volitelné hluboké protokoly požadavků/překladů v `logs/` pokud `ENABLE_REQUEST_LOGS=true`
|
||||
- Koncové body použití dashboardu ( `/api/usage/*` ) pro spotřebu v uživatelském rozhraní
|
||||
|
||||
## Hranice citlivé z hlediska zabezpečení
|
||||
|
||||
- Tajný kód JWT ( `JWT_SECRET` ) zajišťuje ověřování/podepisování souborů cookie relace dashboardu.
|
||||
- Počáteční bootstrap hesla ( `INITIAL_PASSWORD` ) by měl být explicitně nakonfigurován pro zřizování při prvním spuštění.
|
||||
- Tajný klíč API HMAC ( `API_KEY_SECRET` ) zabezpečuje formát vygenerovaného lokálního klíče API.
|
||||
- Tajné klíče/tokeny poskytovatele (klíče/tokeny API) jsou uloženy v lokální 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 ověřování klíče API + ID počítače.
|
||||
|
||||
## Matice prostředí a běhového prostředí
|
||||
|
||||
Proměnné prostředí aktivně používané kódem:
|
||||
|
||||
- Aplikace/autentizace: `JWT_SECRET` , `INITIAL_PASSWORD`
|
||||
- Úložiště: `DATA_DIR`
|
||||
- Chování kompatibilního uzlu: `ALLOW_MULTI_CONNECTIONS_PER_COMPAT_NODE`
|
||||
- Volitelné přepsání úložné základny (Linux/macOS, když `DATA_DIR` není nastaveno): `XDG_CONFIG_HOME`
|
||||
- Bezpečnostní hashování: `API_KEY_SECRET` , `MACHINE_ID_SALT`
|
||||
- Protokolování: `ENABLE_REQUEST_LOGS`
|
||||
- Synchronizace/cloudové URL: `NEXT_PUBLIC_BASE_URL` , `NEXT_PUBLIC_CLOUD_URL`
|
||||
- Odchozí proxy: `HTTP_PROXY` , `HTTPS_PROXY` , `ALL_PROXY` , `NO_PROXY` a varianty s malými písmeny
|
||||
- Příznaky funkcí SOCKS5: `ENABLE_SOCKS5_PROXY` , `NEXT_PUBLIC_ENABLE_SOCKS5_PROXY`
|
||||
- Pomocníci pro platformu/běhové prostředí (ne konfigurace specifická pro aplikaci): `APPDATA` , `NODE_ENV` , `PORT` , `HOSTNAME`
|
||||
|
||||
## Známé architektonické poznámky
|
||||
|
||||
1. `usageDb` a `localDb` sdílejí stejnou základní adresářovou politiku ( `DATA_DIR` -> `XDG_CONFIG_HOME/omniroute` -> `~/.omniroute` ) se starší migrací souborů.
|
||||
2. `/api/v1/route.ts` deleguje na stejný jednotný nástroj pro tvorbu katalogů, 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, zaznamenávač požadavků zapisuje celé záhlaví/tělo; adresář protokolu je považován za citlivý.
|
||||
4. Chování cloudu závisí na správné adrese `NEXT_PUBLIC_BASE_URL` a dosažitelnosti cloudového koncového bodu.
|
||||
5. Adresář `open-sse/` je publikován jako **balíček npm workspace** `@omniroute/open-sse` . Zdrojový kód jej importuje přes `@omniroute/open-sse/...` (vyřešeno pomocí `transpilePackages` v Next.js). Cesty k souborům v tomto dokumentu stále používají název adresáře `open-sse/` pro účely konzistence.
|
||||
6. Grafy v dashboardu používají **Recharts** (založené na SVG) pro přístupné a interaktivní vizualizace analytiky (sloupcové grafy využití modelu, tabulky s rozpisem poskytovatelů s mírou úspěšnosti).
|
||||
7. E2E testy používají **Playwright** ( `tests/e2e/` ), spouštěné pomocí `npm run test:e2e` . Unit testy používají **Node.js test runner** ( `tests/unit/` ), spouštěné pomocí `npm run test:unit` . Zdrojový kód pod `src/` je **TypeScript** ( `.ts` / `.tsx` ); pracovní prostor `open-sse/` zůstává JavaScript ( `.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é limity rychlosti, jistič, zásady), AI (rozpočet promyšlený, systémový výzva, mezipaměť výzev), Pokročilé (proxy).
|
||||
|
||||
## Kontrolní seznam provozního ověření
|
||||
|
||||
- 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`
|
||||
- Základní URL cíle CLI by měla být `http://<host>:20128/v1` , pokud `PORT=20128`
|
||||
63
docs/i18n/cs/AUTO-COMBO.md
Normal file
63
docs/i18n/cs/AUTO-COMBO.md
Normal file
@@ -0,0 +1,63 @@
|
||||
# OmniRoute Auto-Combo Engine
|
||||
|
||||
> Samosprávné řetězce modelů s adaptivním bodováním
|
||||
|
||||
## Jak to funguje
|
||||
|
||||
Systém Auto-Combo dynamicky vybírá nejlepšího poskytovatele/model pro každý požadavek pomocí **6faktorové skórovací funkce** :
|
||||
|
||||
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
|
||||
Náklady na fakturu | 0,20 | Inverzní náklady (levnější = vyšší skóre)
|
||||
LatencyInv | 0,15 | Inverzní latence p95 (rychlejší = vyšší)
|
||||
TaskFit | 0,10 | Skóre zdatnost modelu × typu úlohy
|
||||
Stabilita | 0,10 | Nízká variabilita latence/chyb
|
||||
|
||||
## Balíčky módů
|
||||
|
||||
Balíček | Soustředit | Hmotnost klíče
|
||||
:-- | :-- | :--
|
||||
🚀 **Rychlé odeslání** | Rychlost | latenceInv: 0,35
|
||||
💰 **Úspora nákladů** | Ekonomika | Náklady na účet: 0,40
|
||||
🎯 **Kvalita na prvním místě** | Nejlepší model | taskFit: 0,40
|
||||
📡 **Vhodné pro offline použití** | Dostupnost | kvóta: 0,40
|
||||
|
||||
## Samoléčení
|
||||
|
||||
- **Dočasné vyloučení** : Skóre < 0,2 → vyloučeno na 5 minut (postupné oddlužování, max. 30 minut)
|
||||
- **Upozornění na jistič** : OTEVŘENO → automatické vyloučení; POLOVIČNÍ OTEVŘENO → požadavky sondy
|
||||
- **Režim incidentu** : >50% OTEVŘENO → deaktivovat průzkum, maximalizovat stabilitu
|
||||
- **Obnova po zchlazení** : Po vyloučení je první požadavek „sonda“ se zkráceným časovým limitem.
|
||||
|
||||
## Průzkum banditů
|
||||
|
||||
5 % požadavků (konfigurovatelných) je směrováno k náhodným poskytovatelům k prozkoumání. V režimu incidentu je toto nastavení zakázáno.
|
||||
|
||||
## 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"}'
|
||||
|
||||
# List auto-combos
|
||||
curl http://localhost:20128/api/combos/auto
|
||||
```
|
||||
|
||||
## Úkol Fitness
|
||||
|
||||
Více než 30 modelů hodnocených v 6 typech úkolů ( `coding` , `review` , `planning` , `analysis` , `debugging` , `documentation` ). Podporuje zástupné znaky (např. `*-coder` → vysoké skóre kódování).
|
||||
|
||||
## Soubory
|
||||
|
||||
Soubor | Účel
|
||||
:-- | :--
|
||||
`open-sse/services/autoCombo/scoring.ts` | Skórovací funkce a normalizace poolu
|
||||
`open-sse/services/autoCombo/taskFitness.ts` | Vyhledávání vhodnosti modelu × ú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
|
||||
715
docs/i18n/cs/CHANGELOG.md
Normal file
715
docs/i18n/cs/CHANGELOG.md
Normal file
@@ -0,0 +1,715 @@
|
||||
# Seznam změn
|
||||
|
||||
## [Nevydané]
|
||||
|
||||
---
|
||||
|
||||
## [2.7.8] — 18. 3. 2026
|
||||
|
||||
> Sprint: Chyba ukládání rozpočtu + funkce kombinovaného agenta v uživatelském rozhraní + oprava zabezpečení tagu omniModel.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(budget)** : „Uložit limity“ již nevrací chybu 422 — `warningThreshold` se nyní správně odesílá jako zlomek (0–1) místo procenta (0–100) (#451)
|
||||
- **oprava(kombinace)** : interní tag mezipaměti `<omniModel>` je nyní odstraněn před přeposíláním požadavků poskytovatelům, čímž se zabrání přerušení relace mezipaměti (#454)
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(combos)** : Do modálního okna pro vytváření/úpravy komb přidána sekce Funkce agenta – zpřístupnění přepsání `system_message` , `tool_filter_regex` a `context_cache_protection` přímo z dashboardu (#454)
|
||||
|
||||
---
|
||||
|
||||
## [2.7.7] — 18. 3. 2026
|
||||
|
||||
> Sprint: Pád Dockeru pino, oprava workeru Codex CLI responses, synchronizace zámků balíčků.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava(docker)** : `pino-abstract-transport` a `pino-pretty` jsou nyní explicitně kopírovány ve fázi Docker Runner — Samostatné trasování Next.js tyto závislosti peerů přehlíží, což způsobuje pád `Cannot find module pino-abstract-transport` při spuštění (#449)
|
||||
- **fix(responses)** : Odstranění `initTranslators()` z trasy `/v1/responses` — worker Next.js `the worker has exited` uncaughtException při požadavcích Codex CLI (#450)
|
||||
|
||||
### 🔧 Údržba
|
||||
|
||||
- **chore(deps)** : `package-lock.json` je nyní commitován při každém upgradu verze, aby se zajistilo, že Docker `npm ci` použije přesné verze závislostí.
|
||||
|
||||
---
|
||||
|
||||
## [2.7.5] — 18. 3. 2026
|
||||
|
||||
> Sprint: Vylepšení uživatelského rozhraní a oprava kontroly stavu rozhraní Windows CLI.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(ux)** : Zobrazit na přihlašovací stránce nápovědu k výchozímu heslu — noví uživatelé nyní pod polem pro zadání hesla vidí `"Default password: 123456"` (#437)
|
||||
- **fix(cli)** : Claude CLI a další nástroje nainstalované npm jsou nyní správně detekovány jako spustitelné ve Windows — spawn používá `shell:true` k rozpoznání `.cmd` wrapperů přes PATHEXT (#447)
|
||||
|
||||
---
|
||||
|
||||
## [2.7.4] — 18. 3. 2026
|
||||
|
||||
> Sprint: Panel vyhledávacích nástrojů, opravy i18n, limity Copilota, oprava validace Serperu.
|
||||
|
||||
### 🚀 Vlastnosti
|
||||
|
||||
- **feat(search)** : Přidáno hřiště pro vyhledávání (10. koncový bod), stránka s nástroji pro vyhledávání s porovnáním poskytovatelů/kanálovým přeřazením/historií vyhledávání, lokální směrování pro přeřazení, ochrana autorizace ve vyhledávacím API (#443 od @Regis-RCR)
|
||||
- Nová trasa: `/dashboard/search-tools`
|
||||
- Položka postranního panelu v sekci Ladění
|
||||
- `GET /api/search/providers` a `GET /api/search/stats` s ochranou autorizace
|
||||
- Lokální směrování provider_nodes pro `/v1/rerank`
|
||||
- 30+ klíčů i18n ve vyhledávacím jmenném prostoru
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(search)** : Oprava normalizátoru Brave News (vracel 0 výsledků), vynucení zkrácení max_results po normalizaci, oprava URL pro načítání stránek z koncových bodů (#443 od @Regis-RCR)
|
||||
- **fix(analytics)** : Lokalizace popisků dnů/dat v analytických nástrojích — nahrazení pevně zakódovaných portugalských řetězců pomocí `Intl.DateTimeFormat(locale)` (#444 od @hijak)
|
||||
- **oprava(copilot)** : Oprava zobrazení typu účtu GitHub Copilot, filtrování zavádějících řádků neomezených kvót z dashboardu limitů (#445 od @hijak)
|
||||
- **oprava(poskytovatelé)** : Zastavit odmítání platných klíčů Serper API – odpovědi jiné než 4xx považovat za platné ověřování (#446 od @hijak)
|
||||
|
||||
---
|
||||
|
||||
## [2.7.3] — 18. 3. 2026
|
||||
|
||||
> Sprint: Oprava záložní kvóty pro přímé API Codexu.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava(codex)** : Blokování týdenních vyčerpávajících účtů v přímém záložním rozhraní API (#440)
|
||||
- Porovnávání prefixů `resolveQuotaWindow()` : `"weekly"` nyní odpovídá klíčům mezipaměti `"weekly (7d)"`
|
||||
- `applyCodexWindowPolicy()` správně vynucuje přepínání `useWeekly` / `use5h`
|
||||
- 4 nové regresní testy (celkem 766)
|
||||
|
||||
---
|
||||
|
||||
## [2.7.2] — 18. 3. 2026
|
||||
|
||||
> Sprint: Opravy kontrastu uživatelského rozhraní v režimu Light.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(logs)** : Oprava kontrastu světelného režimu v protokolech požadavků, tlačítek filtrů a kombinovaného odznaku (#378)
|
||||
- Tlačítka filtrů Chyba/Úspěch/Kombinace jsou nyní čitelná i ve světlém režimu.
|
||||
- Odznak kombinované řady používá ve světlém režimu silnější fialovou barvu
|
||||
|
||||
---
|
||||
|
||||
## [2.7.1] — 17. 3. 2026
|
||||
|
||||
> Sprint: Sjednocené směrování webového vyhledávání (POST /v1/search) s 5 poskytovateli + opravy zabezpečení Next.js 16.1.7 (6 CVE).
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **feat(search)** : Sjednocené směrování webového vyhledávání — `POST /v1/search` s 5 poskytovateli (Serper, Brave, Perplexity, Exa, Tavily)
|
||||
- Automatické přepnutí napříč poskytovateli, více než 6 500 bezplatných vyhledávání/měsíc
|
||||
- Mezipaměť v paměti se slučováním požadavků (konfigurovatelné TTL)
|
||||
- Dashboard: Karta Analytika vyhledávání v `/dashboard/analytics` s rozpisem poskytovatelů, mírou zásahů do mezipaměti a sledováním nákladů
|
||||
- Nové API: `GET /api/v1/search/analytics` pro statistiky vyhledávacích požadavků
|
||||
- Migrace databáze: sloupec `request_type` v `call_logs` pro sledování požadavků mimo chat
|
||||
- Ověření Zod ( `v1SearchSchema` ), chráněné autorizací, náklady zaznamenány pomocí `recordCost()`
|
||||
|
||||
### 🔒 Bezpečnost
|
||||
|
||||
- **deps** : Next.js 16.1.6 → 16.1.7 — opravuje 6 CVE:
|
||||
- **Kritické** : CVE-2026-29057 (pašování HTTP požadavků přes http-proxy)
|
||||
- **Vysoká** : CVE-2026-27977, CVE-2026-27978 (WebSocket + akce serveru)
|
||||
- **Médium** : CVE-2026-27979, CVE-2026-27980, CVE-2026-jcc7
|
||||
|
||||
### 📁 Nové soubory
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`open-sse/handlers/search.ts` | Vyhledávací obslužná rutina s routováním 5 poskytovatelů
|
||||
`open-sse/config/searchRegistry.ts` | Registr poskytovatelů (autorizace, náklady, kvóta, TTL)
|
||||
`open-sse/services/searchCache.ts` | Mezipaměť v paměti se slučováním požadavků
|
||||
`src/app/api/v1/search/route.ts` | Trasa Next.js (POST + GET)
|
||||
`src/app/api/v1/search/analytics/route.ts` | API pro statistiky vyhledávání
|
||||
`src/app/(dashboard)/dashboard/analytics/SearchAnalyticsTab.tsx` | Karta analytického panelu
|
||||
`src/lib/db/migrations/007_search_request_type.sql` | Migrace databáze
|
||||
`tests/unit/search-registry.test.mjs` | 277 řádků jednotkových testů
|
||||
|
||||
---
|
||||
|
||||
## [2.7.0] — 17. 3. 2026
|
||||
|
||||
> Sprint: Funkce inspirované ClawRouterem – příznak volání toolCalling, vícejazyčná detekce záměru, benchmarkem řízený fallback, deduplikace požadavků, plugin RouterStrategy, ceny Grok-4 Fast + GLM-5 + MiniMax M2.5 + Kimi K2.5.
|
||||
|
||||
### ✨ Nové modely a ceny
|
||||
|
||||
- **feat. (ceny)** : xAI Grok-4 Fast — `$0.20/$0.50 per 1M tokens` , latence 1143 ms p50, podpora volání nástrojů
|
||||
- **feat. (ceny)** : xAI Grok-4 (standardní) — `$0.20/$1.50 per 1M tokens` , což je důvodem k odmítnutí.
|
||||
- **výkon (ceny)** : GLM-5 přes Z.AI — `$0.5/1M` , 128 tisíc výstupních kontextů
|
||||
- **výkon (ceny)** : MiniMax M2.5 — `$0.30/1M input` , uvažování + agentní úkoly
|
||||
- **feat.(ceny)** : DeepSeek V3.2 — aktualizované ceny `$0.27/$1.10 per 1M`
|
||||
- **výkon (cena)** : Kimi K2.5 přes Moonshot API — přímý přístup k Moonshot API
|
||||
- **feat(providers)** : Přidán poskytovatel Z.AI (alias `zai` ) — rodina GLM-5 s výstupem 128K
|
||||
|
||||
### 🧠 Směrovací inteligence
|
||||
|
||||
- **feat(registry)** : příznak `toolCalling` pro každý model v registru poskytovatelů – kombinace nyní mohou preferovat/vyžadovat modely s možností volání nástrojů
|
||||
- **feat(scoring)** : Detekce vícejazyčného záměru pro skórování AutoCombo — skriptové/jazykové vzory PT/ZH/ES/AR ovlivňují výběr modelu podle kontextu požadavku
|
||||
- **feat(fallback)** : Řetězce záložních metod řízené benchmarky — skutečná data o latenci (p50 z `comboMetrics` ) používaná k dynamickému přeskupení priorit záložních metod
|
||||
- **feat(dedup)** : Vyžádání deduplikace pomocí content-hash — 5sekundové okno idempotence zabraňuje duplicitním voláním poskytovatele v opakovaném pokusu o odeslání klientům
|
||||
- **feat(router)** : Připojitelné rozhraní `RouterStrategy` v `autoCombo/routerStrategy.ts` — lze vložit vlastní logiku směrování bez úpravy jádra
|
||||
|
||||
### 🔧 Vylepšení serveru MCP
|
||||
|
||||
- **feat(mcp)** : 2 nová pokročilá schémata nástrojů: `omniroute_get_provider_metrics` (p50/p95/p99 na poskytovatele) a `omniroute_explain_route` (vysvětlení rozhodnutí o směrování)
|
||||
- **feat(mcp)** : Aktualizovány rozsahy autorizace nástroje MCP – přidán rozsah `metrics:read` pro nástroje pro metriky poskytovatelů
|
||||
- **feat(mcp)** : `omniroute_best_combo_for_task` nyní akceptuje parametr `languageHint` pro vícejazyčné směrování
|
||||
|
||||
### 📊 Pozorovatelnost
|
||||
|
||||
- **feat(metrics)** : Soubor `comboMetrics.ts` rozšířen o sledování percentilů latence v reálném čase pro každého poskytovatele/účet.
|
||||
- **feat(health)** : Rozhraní Health API ( `/api/monitoring/health` ) nyní vrací pole `p50Latency` a `errorRate` pro každého poskytovatele.
|
||||
- **feat(usage)** : Migrace historie použití pro sledování latence pro jednotlivé modely
|
||||
|
||||
### 🗄️ Migrace databází
|
||||
|
||||
- **feat(migrations)** : Nový sloupec `latency_p50` v tabulce `combo_metrics` — nulový, bezpečný pro stávající uživatele
|
||||
|
||||
### 🐛 Opravy chyb / Uzavření
|
||||
|
||||
- **close(#411)** : rozlišení hašovaných modulů better-sqlite3 ve Windows — opraveno ve verzi 2.6.10 (f02c5b5)
|
||||
- **close(#409)** : Dokončení chatu GitHub Copilot selhává u modelů Claude při připojení souborů – opraveno ve verzi 2.6.9 (838f1d6)
|
||||
- **close(#405)** : Duplikát #411 – vyřešeno
|
||||
|
||||
## [2.6.10] — 17. 3. 2026
|
||||
|
||||
> Oprava pro Windows: stažení předkompilovaného better-sqlite3 bez node-gyp/Pythonu/MSVC (#426).
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(install/#426)** : Ve Windows dříve selhával příkaz `npm install -g omniroute` s `better_sqlite3.node is not a valid Win32 application` , protože přiložený nativní binární soubor byl zkompilován pro Linux. Přidává **strategii 1.5** do `scripts/postinstall.mjs` : používá `@mapbox/node-pre-gyp install --fallback-to-build=false` (přiloženo v rámci `better-sqlite3` ) ke stažení správného předkompilovaného binárního souboru pro aktuální OS/arch bez nutnosti použití jakýchkoli nástrojů pro sestavení (žádný node-gyp, žádný Python, žádný MSVC). Vrací se k `npm rebuild` pouze v případě, že stahování selže. Přidává chybové zprávy specifické pro platformu s jasnými pokyny k ruční opravě.
|
||||
|
||||
---
|
||||
|
||||
## [2.6.9] — 17. 3. 2026
|
||||
|
||||
> Opravy CI (t11 s libovolným rozpočtem), oprava chyby č. 409 (souborové přílohy přes Copilot+Claude), korekce pracovního postupu vydání.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(ci)** : Odstranění slova „any“ z komentářů v `openai-responses.ts` a `chatCore.ts` , které neprošly kontrolou rozpočtu t11 `\bany\b` (falešně pozitivní výsledek z počítání regexů v komentářích).
|
||||
- **oprava(chatCore)** : Normalizovat nepodporované typy částí obsahu před přeposláním poskytovatelům (#409 — Kurzor odesílá `{type:"file"}` když jsou připojeny soubory `.md` ; Copilot a další poskytovatelé kompatibilní s OpenAI odmítají s "type musí být buď 'image_url', nebo 'text'"; oprava převádí bloky `file` / `document` na `text` a odstraňuje neznámé typy)
|
||||
|
||||
### 🔧 Pracovní postup
|
||||
|
||||
- **chore(generate-release)** : Přidat pravidlo pro atomický commit — navýšení verze ( `npm version patch` ) MUSÍ proběhnout před commitem souborů funkcí, aby se zajistilo, že tag vždy ukazuje na commit obsahující všechny změny verzí dohromady.
|
||||
|
||||
---
|
||||
|
||||
## [2.6.8] — 17. 3. 2026
|
||||
|
||||
> Sprint: Kombinace jako agent (systémový příkaz + filtr nástrojů), ochrana kontextového ukládání do mezipaměti, automatická aktualizace, podrobné protokoly, MITM Kiro IDE.
|
||||
|
||||
### 🗄️ Migrace databází (bez nutnosti aktualizace – bezpečné pro stávající uživatele)
|
||||
|
||||
- **005_combo_agent_fields.sql** : `ALTER TABLE combos ADD COLUMN system_message TEXT DEFAULT NULL` , `tool_filter_regex TEXT DEFAULT NULL` , `context_cache_protection INTEGER DEFAULT 0`
|
||||
- **006_detailed_request_logs.sql** : Nová tabulka `request_detail_logs` s triggerem kruhového bufferu s 500 záznamy, možnost přihlášení přes přepínač nastavení
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(combo)** : Přepsání systémových zpráv pro Combo (#399 — pole `system_message` nahrazuje nebo vkládá systémový výzvu před přesměrováním poskytovateli)
|
||||
- **feat(combo)** : Regulární výraz filtru nástrojů pro každou kombinaci (#399 — `tool_filter_regex` uchovává pouze nástroje odpovídající vzoru; podporuje formáty OpenAI + Anthropic)
|
||||
- **feat(combo)** : Ochrana před ukládáním do mezipaměti kontextu (#401 — `context_cache_protection` označuje odpovědi s `<omniModel>provider/model</omniModel>` a modelem pins pro zajištění kontinuity relace)
|
||||
- **feat(settings)** : Automatická aktualizace přes Nastavení (#320 — `GET /api/system/version` + `POST /api/system/update` — kontroluje registr npm a aktualizuje na pozadí s restartem pm2)
|
||||
- **feat(logs)** : Podrobné protokoly požadavků (#378 — zachycuje kompletní těla procesů ve 4 fázích: požadavek klienta, přeložený požadavek, odpověď poskytovatele, odpověď klienta — přepínání přihlášení, ořezávání na 64 kB, kruhová vyrovnávací paměť s 500 záznamy)
|
||||
- **feat(mitm)** : Profil MITM Kiro IDE (#336 — `src/mitm/targets/kiro.ts` cílí na api.anthropic.com, znovu využívá stávající infrastrukturu MITM)
|
||||
|
||||
---
|
||||
|
||||
## [2.6.7] — 17. 3. 2026
|
||||
|
||||
> Sprint: Vylepšení SSE, rozšíření lokálních provider_nodes, registr proxy, opravy Claude passthrough.
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(health)** : Kontrola stavu lokálních `provider_nodes` na pozadí s exponenciálním zpožděním (30s→300s) a `Promise.allSettled` pro zamezení blokování (#423, @Regis-RCR)
|
||||
- **feat(embeddings)** : Směrování `/v1/embeddings` do lokálních uzlů `provider_nodes` — `buildDynamicEmbeddingProvider()` s ověřením názvu hostitele (#422, @Regis-RCR)
|
||||
- **feat(audio)** : Směrování TTS/STT do lokálních `provider_nodes` — `buildDynamicAudioProvider()` s ochranou SSRF (#416, @Regis-RCR)
|
||||
- **feat(proxy)** : Registr proxy, API pro správu a zobecnění limitů kvót (#429, @Regis-RCR)
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(sse)** : Odstranění polí specifických pro Claude ( `metadata` , `anthropic_version` ), pokud je cíl kompatibilní s OpenAI (#421, @prakersh)
|
||||
- **fix(sse)** : Extrahuje využití Claude SSE ( `input_tokens` , `output_tokens` , cache tokeny) v režimu průchozího streamu (#420, @prakersh)
|
||||
- **fix(sse)** : Generování záložního `call_id` pro volání nástrojů s chybějícími/prázdnými ID (#419, @prakersh)
|
||||
- **oprava(sse)** : Průchod mezi Claudey a Claudey — přední tělo zcela nedotčeno, bez opětovného překladu (#418, @prakersh)
|
||||
- **fix(sse)** : Filtrovat osiřelé položky `tool_result` po zhuštění kontextu Claude Code, aby se zabránilo chybám 400 (#417, @prakersh)
|
||||
- **fix(sse)** : Přeskočit volání nástrojů s prázdnými názvy v překladači Responses API, aby se zabránilo nekonečným smyčkám `placeholder_tool` (#415, @prakersh)
|
||||
- **fix(sse)** : Odstranění prázdných bloků textového obsahu před překladem (#427, @prakersh)
|
||||
- **fix(api)** : Přidáno `refreshable: true` do testovací konfigurace Claude OAuth (#428, @prakersh)
|
||||
|
||||
### 📦 Závislosti
|
||||
|
||||
- Zvýšení `vitest` , `@vitest/*` a související devDependencies (#414, @dependabot)
|
||||
|
||||
---
|
||||
|
||||
## [2.6.6] — 17. 3. 2026
|
||||
|
||||
> Oprava: Kompatibilita s Turbopackem/Dockerem — odebrání protokolu `node:` ze všech importů `src/` .
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(build)** : Z příkazů `import` v 17 souborech v `src/` byl odstraněn prefix `node:` protocol. Importy `node:fs` , `node:path` , `node:url` , `node:os` atd. způsobovaly, že `Ecmascript file had an error` v sestaveních Turbopack (Next.js 15 Docker) a při upgradech ze starších globálních instalací npm. Dotčené soubory: `migrationRunner.ts` , `core.ts` , `backup.ts` , `prompts.ts` , `dataPaths.ts` a 12 dalších v `src/app/api/` a `src/lib/` .
|
||||
- **chore(workflow)** : Aktualizován `generate-release.md` , aby synchronizace Docker Hubu a nasazení duálního VPS zahrnovaly **povinné** kroky v každé verzi.
|
||||
|
||||
---
|
||||
|
||||
## [2.6.5] — 17. 3. 2026
|
||||
|
||||
> Sprint: filtrování parametrů modelu uvažování, oprava chyby 404 lokálního poskytovatele, poskytovatel Kilo Gateway, vylepšení závislostí.
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **feat(api)** : Přidán **Kilo Gateway** ( `api.kilo.ai` ) jako nový poskytovatel API klíčů (alias `kg` ) — více než 335 modelů, 6 bezplatných modelů, 3 modely automatického směrování ( `kilo-auto/frontier` , `kilo-auto/balanced` , `kilo-auto/free` ). Průchozí modely podporovány přes endpoint `/api/gateway/models` . (PR #408 od @Regis-RCR)
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(sse)** : Odstranění nepodporovaných parametrů pro modely uvažování (o1, o1-mini, o1-pro, o3, o3-mini). Modely v rodině `o1` / `o3` odmítají `temperature` , `top_p` , `frequency_penalty` , `presence_penalty` , `logprobs` , `top_logprobs` a `n` s HTTP 400. Parametry jsou nyní odstraňovány na vrstvě `chatCore` před přeposíláním. Používá deklarativní pole `unsupportedParams` pro každý model a předpočítanou mapu O(1) pro vyhledávání. (PR #412 od @Regis-RCR)
|
||||
- **fix(sse)** : Kód 404 lokálního poskytovatele nyní vede k **uzamčení pouze modelu (5 sekund)** namísto uzamčení na úrovni připojení (2 minuty). Když lokální inferenční backend (Ollama, LM Studio, oMLX) vrátí kód 404 pro neznámý model, připojení zůstane aktivní a ostatní modely okamžitě pokračují v práci. Také opravuje již existující chybu, kdy `model` nebyl předán funkci `markAccountUnavailable()` . Lokální poskytovatelé detekováni pomocí názvu hostitele ( `localhost` , `127.0.0.1` , `::1` , rozšiřitelné pomocí proměnné prostředí `LOCAL_HOSTNAMES` ). (PR #410 od @Regis-RCR)
|
||||
|
||||
### 📦 Závislosti
|
||||
|
||||
- `better-sqlite3` 12.6.2 → 12.8.0
|
||||
- `undici` 7.24.2 → 7.24.4
|
||||
- `https-proxy-agent` 7 → 8
|
||||
- `agent-base` 7 → 8
|
||||
|
||||
---
|
||||
|
||||
## [2.6.4] — 17. 3. 2026
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(providers)** : Odstraněny neexistující názvy modelů u 5 poskytovatelů:
|
||||
- **gemini / gemini-cli** : odstraněny `gemini-3.1-pro/flash` a `gemini-3-*-preview` (neexistují v Google API v1beta); nahrazeny `gemini-2.5-pro` , `gemini-2.5-flash` , `gemini-2.0-flash` , `gemini-1.5-pro/flash`
|
||||
- **antigravity** : odstraněny `gemini-3.1-pro-high/low` a `gemini-3-flash` (neplatné interní aliasy); nahrazeny skutečnými modely z verze 2.x
|
||||
- **github (Copilot)** : odstraněny `gemini-3-flash-preview` a `gemini-3-pro-preview` ; nahrazeny `gemini-2.5-flash`
|
||||
- **nvidia** : opraveno `nvidia/llama-3.3-70b-instruct` → `meta/llama-3.3-70b-instruct` (NVIDIA NIM používá pro modely Meta jmenný prostor `meta/` /); přidány `nvidia/llama-3.1-70b-instruct` a `nvidia/llama-3.1-405b-instruct`
|
||||
- **fix(db/combo)** : Aktualizováno `free-stack` combo na vzdálené databázi: odstraněno `qw/qwen3-coder-plus` (prošlý obnovovací token), opraveno `nvidia/llama-3.3-70b-instruct` → `nvidia/meta/llama-3.3-70b-instruct` , opraveno `gemini/gemini-3.1-flash` → `gemini/gemini-2.5-flash` , přidáno `if/deepseek-v3.2`
|
||||
|
||||
---
|
||||
|
||||
## [2.6.3] — 16. 3. 2026
|
||||
|
||||
> Sprint: hash-strip zod/pino zapečený do build pipeline, přidán syntetický poskytovatel, opravena cesta VPS PM2.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(build)** : Turbopack hash-strip se nyní spouští při **kompilaci** pro VŠECHNY balíčky — nejen `better-sqlite3` . Krok 5.6 v `prepublish.mjs` prochází každý `.js` v `app/.next/server/` a odstraňuje 16znakovou hexadecimální příponu z jakékoli hashované `require()` . Opravuje `zod-dcb22c...` , `pino-...` atd. MODULE_NOT_FOUND u globálních instalací npm. Zavírá #398.
|
||||
- **Oprava (nasazení)** : PM2 na obou VPS ukazoval na zastaralé adresáře git-clone. V globálním balíčku npm překonfigurováno na `app/server.js` . Aktualizován pracovní postup `/deploy-vps` pro použití `npm pack + scp` (registr npm odmítá balíčky o velikosti 299 MB).
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(provider)** : Synthetic ( [synthetic.new](https://synthetic.new) ) — inference kompatibilní s OpenAI zaměřená na soukromí. `passthroughModels: true` pro dynamický katalog modelů HuggingFace. Počáteční modely: Kimi K2.5, MiniMax M2.5, GLM 4.7, DeepSeek V3.2. (PR #404 od @Regis-RCR)
|
||||
|
||||
### 📋 Problémy uzavřeny
|
||||
|
||||
- **zavřít #398** : regrese hashování npm — opraveno hashováním při kompilaci v prepublish
|
||||
- **triáž č. 324** : Snímek obrazovky s chybou bez kroků – požadovány podrobnosti o reprodukci
|
||||
|
||||
---
|
||||
|
||||
## [2.6.2] — 16. 3. 2026
|
||||
|
||||
> Sprint: hashování modulů kompletně opraveno, sloučeny 2 PR (filtr Anthropic tools + vlastní cesty k endpointům), přidán poskytovatel Alibaba Cloud DashScope, uzavřeny 3 zastaralé problémy.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(build)** : Rozšířeno hashování `externals` webpacku tak, aby zahrnovalo VŠECHNY `serverExternalPackages` , nejen `better-sqlite3` . Next.js 16 Turbopack hashuje `zod` , `pino` a všechny ostatní externí balíčky serveru do názvů jako `zod-dcb22c6336e0bc69` , které za běhu v `node_modules` neexistují. HASH_PATTERN regex catch-all nyní odstraňuje 16znakovou příponu a vrací se k základnímu názvu balíčku. Také přidána `NEXT_PRIVATE_BUILD_WORKER=0` v `prepublish.mjs` pro posílení režimu webpacku a následné skenování po sestavení, které hlásí všechny zbývající hashované reference. (#396, #398, PR #403)
|
||||
- **fix(chat)** : Názvy nástrojů v anthropic formátu ( `tool.name` bez wrapperu `.function` ) byly tiše vynechány filtrem prázdných názvů zavedeným v bodě #346. LiteLLM proxyuje požadavky s prefixem `anthropic/` ve formátu Anthropic Messages API, což způsobuje filtrování všech nástrojů a Anthropic vrací chybu `400: tool_choice.any may only be specified while providing tools` . Opraveno návratem k `tool.name` , když chybí `tool.function.name` . Přidáno 8 regresních jednotkových testů. (PR #397)
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(api)** : Vlastní cesty koncových bodů pro uzly poskytovatelů kompatibilní s OpenAI — konfigurace `chatPath` a `modelsPath` pro každý uzel (např. `/v4/chat/completions` ) v uživatelském rozhraní pro připojení poskytovatele. Zahrnuje migraci databáze ( `003_provider_node_custom_paths.sql` ) a sanitizaci cesty URL (bez `..` traversal, musí začínat znakem `/` ). (PR #400)
|
||||
- **feat(provider)** : Alibaba Cloud DashScope přidán jako poskytovatel kompatibilní s OpenAI. Mezinárodní endpoint: `dashscope-intl.aliyuncs.com/compatible-mode/v1` . 12 modelů: `qwen-max` , `qwen-plus` , `qwen-turbo` , `qwen3-coder-plus/flash` , `qwq-plus` , `qwq-32b` , `qwen3-32b` , `qwen3-235b-a22b` . Autorizace: Nosný API klíč.
|
||||
|
||||
### 📋 Problémy uzavřeny
|
||||
|
||||
- **zavřít #323** : Chyba připojení Cline `[object Object]` – opraveno ve verzi 2.3.7; uživateli bylo doručeno pokyny k upgradu z verze 2.2.9
|
||||
- **zavřít #337** : Sledování úvěru Kiro — implementováno ve verzi 2.5.5 (#381); odkázalo uživatele na Dashboard → Použití
|
||||
- **triage #402** : Poškozený soubor ARM64 macOS DMG – požadovaná verze macOS, přesná chyba a doporučené alternativní řešení `xattr -d com.apple.quarantine`
|
||||
|
||||
---
|
||||
|
||||
## [2.6.1] — 15. 3. 2026
|
||||
|
||||
> Kritická oprava při spuštění: Globální instalace npm v2.6.0 havarovaly s chybou 500 kvůli chybě hashování názvů modulů Turbopack/webpack v instrumentačním hooku Next.js 16.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(build)** : Vynutit, aby byl `better-sqlite3` vždy vyžadován přesným názvem balíčku v balíčku webpack server. Next.js 16 zkompiloval instrumentační hook do samostatného chunku a vygeneroval `require('better-sqlite3-<hash>')` — hashovaný název modulu, který neexistuje v `node_modules` — přestože byl balíček uveden v `serverExternalPackages` . Do konfigurace webpacku serveru byla přidána explicitní funkce `externals` , takže bundler vždy vygeneruje `require('better-sqlite3')` , čímž se vyřeší `500 Internal Server Error` při spuštění čistých globálních instalací. (#394, PR #395)
|
||||
|
||||
### 🔧 CI
|
||||
|
||||
- **ci** : Do `npm-publish.yml` přidána `workflow_dispatch` se zabezpečením synchronizace verzí pro manuální spouštěče (#392).
|
||||
- **ci** : Přidán `workflow_dispatch` do `docker-publish.yml` , aktualizovány akce GitHubu na nejnovější verze (#392)
|
||||
|
||||
---
|
||||
|
||||
## [2.6.0] - 15. 3. 2026
|
||||
|
||||
> Sprint řešení problémů: Opraveny 4 chyby, vylepšeno uživatelské rozhraní protokolů, přidáno sledování kreditů Kiro.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava(média)** : ComfyUI a SD WebUI se již nezobrazují v seznamu poskytovatelů na stránce Média, pokud nejsou nakonfigurovány — při připojení načtou `/api/providers` a skryjí lokální poskytovatele bez připojení (#390)
|
||||
- **oprava(auth)** : Round-robin již po zpoždění znovu nevybírá účty s omezenou rychlostí ihned – `backoffLevel` se nyní používá jako primární třídicí klíč v rotaci LRU (#340)
|
||||
- **oprava(oauth)** : iFlow (a další poskytovatelé, kteří přesměrovávají na své vlastní uživatelské rozhraní) již nenechávají modální okno OAuth zaseknuté na „Čekání na autorizaci“ – detektor zavřených vyskakovacích oken automaticky přechází do režimu ručního zadávání URL (#344)
|
||||
- **oprava(logy)** : Tabulka protokolů požadavků je nyní čitelná ve světlém režimu – stavové odznaky, počty tokenů a kombinované tagy používají adaptivní `dark:` barevné třídy (#378)
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **feat(kiro)** : Do fetcheru využití přidáno sledování kreditů Kiro — dotazy `getUserCredits` z endpointu AWS CodeWhisperer (#337)
|
||||
|
||||
### 🛠 Domácí práce
|
||||
|
||||
- **chore(tests)** : Zarovnání `test:plan3` , `test:fixes` , `test:security` pro použití stejného zavaděče `tsx/esm` jako u `npm test` – eliminuje falešně negativní výsledky rozlišení modulů v cílených bězích (PR #386)
|
||||
|
||||
---
|
||||
|
||||
## [2.5.9] - 15. 3. 2026
|
||||
|
||||
> Oprava nativní passthrough Codexu + posílení validace těla trasy.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(codex)** : Zachovává nativní průchod Responses API pro klienty Codexu – zabraňuje zbytečným mutacím překladu (PR #387)
|
||||
- **fix(api)** : Ověřování těl požadavků na trasách pro stanovení cen/synchronizaci a směrování úloh – zabraňuje pádům způsobeným chybně formátovanými vstupy (PR #388)
|
||||
- **fix(auth)** : Tajné hodnoty JWT přetrvávají i po restartech pomocí `src/lib/db/secrets.ts` — eliminuje chyby 401 po restartu PM2 (PR #388)
|
||||
|
||||
---
|
||||
|
||||
## [2.5.8] - 15. 3. 2026
|
||||
|
||||
> Oprava sestavení: obnovení připojení VPS přerušeného nedokončeným publikováním v2.5.7.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava(build)** : `scripts/prepublish.mjs` se stále používají, zastaralý příznak `--webpack` způsobuje tiché selhání samostatného sestavení Next.js — publikování npm dokončeno bez `app/server.js` , což narušuje nasazení VPS
|
||||
|
||||
---
|
||||
|
||||
## [2.5.7] - 15. 3. 2026
|
||||
|
||||
> Opravy chyb při zpracování v Media Playground.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava(média)** : Přepis „Vyžadován klíč API“ falešně pozitivní, pokud zvuk neobsahuje žádnou řeč (hudba, ticho) – nyní se místo toho zobrazuje „Není detekována žádná řeč“
|
||||
- **oprava(media)** : `upstreamErrorResponse` v `audioTranscription.ts` a `audioSpeech.ts` nyní vrací správný JSON ( `{error:{message}}` ), což umožňuje správnou detekci chyb přihlašovacích údajů 401/403 v MediaPageClient
|
||||
- **oprava(média)** : `parseApiError` nyní zpracovává pole `err_msg` v Deepgramu a detekuje `"api key"` v chybových zprávách pro přesnou klasifikaci chyb přihlašovacích údajů.
|
||||
|
||||
---
|
||||
|
||||
## [2.5.6] - 15. 3. 2026
|
||||
|
||||
> Kritické opravy zabezpečení/autentizace: OAuth v Antigravity nefunkční + relace JWT ztraceny po restartu.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(oauth) #384** : Antigravity Google OAuth nyní správně odesílá `client_secret` do koncového bodu tokenu. Záložní volbou pro `ANTIGRAVITY_OAUTH_CLIENT_SECRET` byl prázdný řetězec, což je chyba – `client_secret` tedy nebyl v požadavku nikdy zahrnut, což způsobovalo chyby `"client_secret is missing"` u všech uživatelů bez vlastní proměnné prostředí. Zavírá #383.
|
||||
- **fix(auth) #385** : `JWT_SECRET` je nyní ukládán do SQLite ( `namespace='secrets'` ) při první generaci a znovu načten při následných spuštěních. Dříve byl při každém spuštění procesu generován nový náhodný tajný klíč, který po jakémkoli restartu nebo upgradu zneplatňoval všechny existující soubory cookie/relace. Ovlivňuje `JWT_SECRET` i `API_KEY_SECRET` . Zavírá #382.
|
||||
|
||||
---
|
||||
|
||||
## [2.5.5] - 15. 3. 2026
|
||||
|
||||
> Oprava odstranění duplicitních dat v seznamu modelů, posílení samostatného sestavení Electronu a sledování kreditů Kiro.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **fix(models) #380** : `GET /api/models` nyní zahrnuje aliasy poskytovatelů při sestavování filtru aktivního poskytovatele — modely pro `claude` (alias `cc` ) a `github` (alias `gh` ) se vždy zobrazovaly bez ohledu na to, zda bylo nakonfigurováno připojení, protože klíče `PROVIDER_MODELS` jsou aliasy, ale připojení k databázi jsou uložena pod ID poskytovatelů. Opraveno rozšířením každého aktivního ID poskytovatele o jeho alias pomocí `PROVIDER_ID_TO_ALIAS` . Zavírá #353.
|
||||
- **fix(electron) #379** : Nové `scripts/prepare-electron-standalone.mjs` připraví vyhrazený balíček `/.next/electron-standalone` před zabalením Electronu. Pokud je `node_modules` symbolický odkaz, dojde k ukončení s chybou (electron-builder by na sestavovací stroj odeslal běhovou závislost). Multiplatformní sanitizace cest pomocí `path.basename` . Od @kfiramar.
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **feat(kiro) #381** : Sledování zůstatku kreditů Kiro — koncový bod využití nyní vrací data o kreditech pro Kiro účty voláním `codewhisperer.us-east-1.amazonaws.com/getUserCredits` (stejný koncový bod, který Kiro IDE používá interně). Vrací zbývající kredity, celkový limit, datum obnovení a úroveň předplatného. Uzavírá #337.
|
||||
|
||||
## [2.5.4] - 15. 3. 2026
|
||||
|
||||
> Oprava spouštění loggeru, oprava zabezpečení přihlašovacího bootstrapu a vylepšení spolehlivosti vývojářského HMR. Zlepšení infrastruktury CI.
|
||||
|
||||
### 🐛 Opravy chyb (PR #374, #375, #376 od @kfiramar)
|
||||
|
||||
- **oprava(logger) #376** : Obnovit cestu k protokolovacímu modulu pino transport — `formatters.level` v kombinaci s `transport.targets` je odmítnut modulem pino. Konfigurace založené na transportu nyní odstraňují formátovač úrovní pomocí funkce `getTransportCompatibleConfig()` . Také opravuje numerické mapování úrovní v `/api/logs/console` : `30→info, 40→warn, 50→error` (bylo posunuto o jednu).
|
||||
- **oprava(login) #375** : Přihlašovací stránka se nyní bootuje z veřejného endpointu `/api/settings/require-login` namísto chráněného `/api/settings` . V nastaveních chráněných heslem dostávala stránka předběžného ověřování chybu 401 a zbytečně se vracela k bezpečným výchozím hodnotám. Veřejná trasa nyní vrací všechna bootstrapová metadata ( `requireLogin` , `hasPassword` , `setupComplete` ) s konzervativní fallback chybou 200.
|
||||
- **oprava(dev) #374** : Přidání `localhost` a `127.0.0.1` do `allowedDevOrigins` v `next.config.mjs` — HMR websocket byl blokován při přístupu k aplikaci přes loopback adresu, což opakovaně produkovalo varování cross-origin.
|
||||
|
||||
### 🔧 CI a infrastruktura
|
||||
|
||||
- **Oprava chyb ESLint OOM** : `eslint.config.mjs` nyní ignoruje `vscode-extension/**` , `electron/**` , `docs/**` , `app/.next/**` a `clipr/**` — ESLint havaroval s chybou JS haldy OOM skenováním binárních blobů a kompilovaných chunků VS Code.
|
||||
- **Oprava jednotkového testu** : Z 2 testovacích souborů byl odstraněn zastaralý `ALTER TABLE provider_connections ADD COLUMN "group"` – sloupec je nyní součástí základního schématu (přidáno v #373), což způsobovalo `SQLITE_ERROR: duplicate column name` při každém spuštění CI.
|
||||
- **Pre-commit hook** : Do `.husky/pre-commit` přidán `npm run test:unit` — unit testy nyní blokují poškozené commity dříve, než se dostanou do CI.
|
||||
|
||||
## [2.5.3] - 14. 3. 2026
|
||||
|
||||
> Opravy kritických chyb: migrace schématu databáze, načítání spouštěcího prostředí, mazání chyb poskytovatele a oprava popisků i18n. Vylepšení kvality kódu nad každým PR.
|
||||
|
||||
### 🐛 Opravy chyb (PR #369, #371, #372, #373 od @kfiramar)
|
||||
|
||||
- **oprava(db) #373** : Přidání sloupce `provider_connections.group` do základního schématu + migrace zpětného doplnění pro existující databáze — sloupec byl použit ve všech dotazech, ale chyběl v definici schématu
|
||||
- **fix(i18n) #371** : Nahrazení neexistujícího klíče `t("deleteConnection")` existujícím `providers.delete` — oprava `MISSING_MESSAGE: providers.deleteConnection` na stránce s podrobnostmi o poskytovateli
|
||||
- **oprava(auth) #372** : Vymazat zastaralá chybová metadata ( `errorCode` , `lastErrorType` , `lastErrorSource` ) z účtů poskytovatelů po skutečném zotavení – dříve se obnovené účty zobrazovaly jako selhané
|
||||
- **oprava(startup) #369** : Sjednocení načítání env napříč `npm run start` , `run-standalone.mjs` a Electron s ohledem na prioritu `DATA_DIR/.env → ~/.omniroute/.env → ./.env` — zabránění generování nového `STORAGE_ENCRYPTION_KEY` přes existující šifrovanou databázi
|
||||
|
||||
### 🔧 Kvalita kódu
|
||||
|
||||
- Zdokumentované vzory `result.success` vs. `response?.ok` v `auth.ts` (oba úmyslné, nyní vysvětlené)
|
||||
- Normalizované `overridePath?.trim()` v `electron/main.js` pro shodu s `bootstrap-env.mjs`
|
||||
- Přidán komentář k objednávce sloučení `preferredEnv` při spuštění Electronu
|
||||
|
||||
> Oprava kvót pro účty Codex s automatickou rotací, rychlým přepínáním úrovní, modelem gpt-5.4 a označením analytických nástrojů.
|
||||
|
||||
### ✨ Nové funkce (PR #366, #367, #368)
|
||||
|
||||
- **Zásady kvót Codexu (PR #366)** : Okno kvóty 5 hodin/týden pro účet se přepíná v dashboardu poskytovatele. Účty jsou automaticky přeskočeny, když povolená okna dosáhnou prahové hodnoty 90 %, a znovu povoleny po `resetAt` . Zahrnuje `quotaCache.ts` s vedlejším efektem pro získávání statusu zdarma.
|
||||
- **Přepínání rychlé úrovně Codexu (PR #367)** : Dashboard → Nastavení → Úroveň služeb Codexu. Přepínání ve výchozím nastavení vkládá `service_tier: "flex"` pouze pro požadavky Codexu, což snižuje náklady o ~80 %. Celý stack: karta UI + koncový bod API + exekutor + překladač + obnovení po spuštění.
|
||||
- **Model gpt-5.4 (PR #368)** : Přidává `cx/gpt-5.4` a `codex/gpt-5.4` do registru modelů Codex. Regresní test je součástí.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **oprava č. 356** : Analytické grafy (Nejlepší poskytovatel, Podle účtu, Rozdělení poskytovatelů) nyní zobrazují lidsky čitelné názvy/štítky poskytovatelů namísto nezpracovaných interních ID u poskytovatelů kompatibilních s OpenAI.
|
||||
|
||||
> Hlavní vydání: strategie striktně náhodného směrování, řízení přístupu k klíčům API, skupiny připojení, synchronizace externích cen a opravy kritických chyb pro modely myšlení, kombinované testování a validaci názvů nástrojů.
|
||||
|
||||
### ✨ Nové funkce (PR #363 a #365)
|
||||
|
||||
- **Strategie striktně náhodného směrování** : Fisher-Yatesův náhodný balíček s garancí neopakování a serializací mutexů pro souběžné požadavky. Nezávislé balíčky pro každé kombo a providera.
|
||||
- **Řízení přístupu ke klíčům API** : `allowedConnections` (omezení připojení, která může klíč používat), `is_active` (povolení/zakázání klíče s kódem 403), `accessSchedule` (řízení přístupu na základě času), přepínání `autoResolve` , přejmenování klíčů pomocí PATCH.
|
||||
- **Skupiny připojení** : Seskupování připojení poskytovatelů podle prostředí. Harmonické zobrazení na stránce Limity s perzistencí localStorage a inteligentním automatickým přepínáním.
|
||||
- **Synchronizace externích cen (LiteLLM)** : 3stupňové rozlišení cen (uživatelské přepsání → synchronizace → výchozí hodnoty). Možnost přihlášení přes `PRICING_SYNC_ENABLED=true` . Nástroj MCP `omniroute_sync_pricing` . 23 nových testů.
|
||||
- **i18n** : 30 jazyků aktualizováno strategií striktní náhodnosti, řetězce pro správu klíčů API. pt-BR plně přeloženo.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **Oprava č. 355** : Časový limit nečinnosti streamu zvýšen z 60 s na 300 s – zabraňuje přerušení modelů s rozšířeným myšlením (claude-opus-4-6, o3 atd.) během dlouhých fází uvažování. Konfigurovatelné pomocí `STREAM_IDLE_TIMEOUT_MS` .
|
||||
- **Oprava č. 350** : Kombinovaný test nyní obchází `REQUIRE_API_KEY=true` pomocí interní hlavičky a univerzálně používá formát kompatibilní s OpenAI. Časový limit prodloužen z 15 s na 20 s.
|
||||
- **oprava #346** : Nástroje s prázdným `function.name` (přeposláno Claudem Code) jsou nyní filtrovány předtím, než je obdrží upstreamoví poskytovatelé, čímž se zabrání chybám „Neplatný vstup[N].name: prázdný řetězec“.
|
||||
|
||||
### 🗑️ Uzavřené problémy
|
||||
|
||||
- **#341** : Sekce ladění odstraněna – nahrazena je `/dashboard/logs` a `/dashboard/health` .
|
||||
|
||||
> Podpora API Key Round-Robin pro nastavení poskytovatelů s více klíči a potvrzení již zavedeného směrování zástupných znaků a rolování oken kvót.
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **Round-Robin klíčů API (T07)** : Připojení poskytovatelů nyní mohou obsahovat více klíčů API (Upravit připojení → Další klíče API). Požadavky rotují round-robin mezi primárními a dalšími klíči pomocí `providerSpecificData.extraApiKeys[]` . Klíče jsou uchovávány v paměti indexované pro každé připojení – nejsou nutné žádné změny schématu databáze.
|
||||
|
||||
### 📝 Již implementováno (potvrzeno auditem)
|
||||
|
||||
- **Směrování modelu s wildcard znaky (T13)** : soubor `wildcardRouter.ts` s porovnáváním zástupných znaků ve stylu glob ( `gpt*` , `claude-?-sonnet` atd.) je již integrován do `model.ts` s hodnocením specificity.
|
||||
- **Posunování okna kvót (T08)** : `accountFallback.ts:isModelLocked()` již automaticky posouvá okno vpřed – pokud `Date.now() > entry.until` , zámek se okamžitě smaže (žádné blokování zastaralých funkcí).
|
||||
|
||||
> Vylepšení uživatelského rozhraní, doplnění strategií směrování a elegantní zpracování chyb pro omezení využití.
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **Strategie směrování Fill-First a P2C** : Do výběru kombinované strategie přidány strategie `fill-first` (vyčerpání kvóty před přesunem) a `p2c` (výběr Power-of-Two-Choices s nízkou latencí) s kompletními panely s pokyny a barevně odlišenými odznaky.
|
||||
- **Přednastavené modely Free Stack** : Vytvoření kombinace pomocí šablony Free Stack nyní automaticky vyplní 7 nejlepších modelů bezplatných poskytovatelů ve své třídě (Gemini CLI, Kiro, iFlow×2, Qwen, NVIDIA NIM, Groq). Uživatelé stačí aktivovat poskytovatele a ihned získají kombinaci 0 $/měsíc.
|
||||
- **Širší kombo modální okno** : Modální okno pro vytvoření/úpravu komba nyní používá `max-w-4xl` pro pohodlnou úpravu velkých komb.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **Stránka s limity HTTP 500 pro Codex a GitHub** : `getCodexUsage()` a `getGitHubUsage()` nyní vracejí uživatelsky přívětivou zprávu, když poskytovatel vrátí 401/403 (vypršelý token), místo aby vyvolaly chybu 500 na stránce s limity.
|
||||
- **Falešně pozitivní MaintenanceBanner** : Banner již při načítání stránky falešně nezobrazuje „Server je nedostupný“. Opraveno okamžitým voláním `checkHealth()` při připojení a odstraněním zastaralého uzavření `show` -state.
|
||||
- **Popisky ikon poskytovatele** : Tlačítka s ikonami pro úpravu (tužka) a odstranění v řádku připojení poskytovatele nyní obsahují nativní HTML popisky – všech 6 ikon akcí je nyní samodokumentovaných.
|
||||
|
||||
> Několik vylepšení z analýzy problémů komunity, podpora nových poskytovatelů, opravy chyb pro sledování tokenů, směrování modelů a spolehlivost streamování.
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **Inteligentní směrování s ohledem na úlohy (T05)** : Automatický výběr modelu na základě typu obsahu požadavku — kódování → deepseek-chat, analýza → gemini-2.5-pro, vision → gpt-4o, sumarizace → gemini-2.5-flash. Konfigurovatelné v Nastavení. Nové API `GET/PUT/POST /api/settings/task-routing` .
|
||||
- **Poskytovatel HuggingFace** : Přidán HuggingFace Router jako poskytovatel kompatibilní s OpenAI s Llama 3.1 70B/8B, Qwen 2.5 72B, Mistral 7B, Phi-3.5 Mini.
|
||||
- **Poskytovatel Vertex AI** : Přidán poskytovatel Vertex AI (Google Cloud) s Gemini 2.5 Pro/Flash, Gemma 2 27B, Claude přes Vertex.
|
||||
- **Nahrávání souborů do Playgroundu** : Nahrávání zvuku pro přepis, nahrávání obrázků pro modely vidění (automatická detekce podle názvu modelu), inline vykreslování obrázků pro výsledky generování obrázků.
|
||||
- **Vizuální zpětná vazba při výběru modelu** : Již přidané modely v kombinovaném výběru nyní zobrazují zelený odznak ✓ – zabraňuje záměně duplicitních modelů.
|
||||
- **Kompatibilita s Qwen (PR #352)** : Aktualizováno nastavení otisků uživatelského agenta a rozhraní CLI pro kompatibilitu s poskytovateli Qwen.
|
||||
- **Správa stavu round-robin (PR #349)** : Vylepšená logika round-robin pro zpracování vyloučených účtů a správné udržování stavu rotace.
|
||||
- **Uživatelská zkušenost se schránkou (PR #360)** : Vylepšené operace se schránkou s možností zálohování pro nezabezpečené kontexty; vylepšení normalizace nástroje Claude.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **Oprava č. 302 – OpenAI SDK stream=False zanechává tool_calls** : T01 Accept header negotiation již nevynucuje streamování, pokud je `body.stream` explicitně `false` . Způsobovalo to tiché zanechávání tool_calls při použití OpenAI Python SDK v režimu bez streamování.
|
||||
- **Oprava č. 73 — Claude Haiku směrován do OpenAI bez prefixu poskytovatele** : modely `claude-*` odeslané bez prefixu poskytovatele nyní správně směrují k poskytovateli `antigravity` (antropickému). Přidána také heuristika `gemini-*` / `gemma-*` → `gemini` .
|
||||
- **Oprava č. 74 – Počet tokenů je pro streamování Antigravity/Claude vždy 0** : Událost SSE `message_start` , která obsahuje `input_tokens` nebyla analyzována funkcí `extractUsage()` , což způsobovalo pokles všech počtů vstupních tokenů. Sledování vstupních/výstupních tokenů nyní funguje správně pro streamované odpovědi.
|
||||
- **Oprava č. 180 – Duplikáty importovaných modelů bez zpětné vazby** : `ModelSelectModal` nyní zobrazuje ✓ zelené zvýraznění u modelů, které jsou již v kombinaci, takže je zřejmé, že jsou již přidány.
|
||||
- **Chyby generování mediálních stránek** : Výsledky obrázků se nyní vykreslují jako tagy `<img>` místo nezpracovaného JSON. Výsledky přepisu se zobrazují jako čitelný text. Chyby přihlašovacích údajů zobrazují oranžový banner místo tiché chyby.
|
||||
- **Tlačítko pro obnovení tokenu na stránce poskytovatele** : Pro poskytovatele OAuth bylo přidáno uživatelské rozhraní pro ruční obnovení tokenu.
|
||||
|
||||
### 🔧 Vylepšení
|
||||
|
||||
- **Registr poskytovatelů** : Do `providerRegistry.ts` a `providers.ts` (frontend) přidány prvky HuggingFace a Vertex AI.
|
||||
- **Čtení mezipaměti** : Nový `src/lib/db/readCache.ts` pro efektivní ukládání do mezipaměti čtení databáze.
|
||||
- **Mezipaměť kvót** : Vylepšená mezipaměť kvót s vyřazením na základě TTL.
|
||||
|
||||
### 📦 Závislosti
|
||||
|
||||
- `dompurify` → 3.3.3 (PR #347)
|
||||
- `undici` → 7.24.2 (PR #348, #361)
|
||||
- `docker/setup-qemu-action` → v4 (PR #342)
|
||||
- `docker/setup-buildx-action` → v4 (PR #343)
|
||||
|
||||
### 📁 Nové soubory
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`open-sse/services/taskAwareRouter.ts` | Logika směrování s ohledem na úlohy (7 typů úloh)
|
||||
`src/app/api/settings/task-routing/route.ts` | API pro konfiguraci směrování úloh
|
||||
`src/app/api/providers/[id]/refresh/route.ts` | Ruční aktualizace tokenu OAuth
|
||||
`src/lib/db/readCache.ts` | Efektivní mezipaměť pro čtení databáze
|
||||
`src/shared/utils/clipboard.ts` | Zpevněná schránka s funkcí
|
||||
|
||||
## [2.4.1] - 13. 3. 2026
|
||||
|
||||
### 🐛 Oprava
|
||||
|
||||
- **Modální okno s kombinacemi: Šablona Volný zásobník viditelná a výrazná** – Šablona Volný zásobník byla skrytá (4. v mřížce se 3 sloupci). Opraveno: přesunuto na pozici 1, přepnuto na mřížku 2x2, takže jsou viditelné všechny 4 šablony, zelený okraj + zvýraznění odznaku ZDARMA.
|
||||
|
||||
## [2.4.0] - 13. 3. 2026
|
||||
|
||||
> **Hlavní vydání** – ekosystém Free Stack, přepracované transkripční hřiště, více než 44 poskytovatelů, komplexní dokumentace k bezplatné úrovni a vylepšení uživatelského rozhraní napříč všemi oblastmi.
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **Kombinace: Šablona Free Stack** — Nová 4. šablona „Free Stack (0 $)“ využívající round-robin napříč Kiro + iFlow + Qwen + Gemini CLI. Při prvním použití doporučuje předpřipravenou kombinaci s nulovými náklady.
|
||||
- **Média/Přepis: Deepgram jako výchozí** – Deepgram (Nova 3, 200 dolarů zdarma) je nyní výchozím poskytovatelem přepisu. AssemblyAI (50 dolarů zdarma) a Groq Whisper (navždy zdarma) jsou zobrazeny s odznaky bezplatného kreditu.
|
||||
- **README: Sekce „Začít zdarma“** – Nová tabulka s 5 kroky v předběžném souboru README, která ukazuje, jak nastavit umělou inteligenci s nulovými náklady během několika minut.
|
||||
- **README: Kombinace bezplatného přepisu** – Nová sekce s návrhem kombinací Deepgram/AssemblyAI/Groq a informacemi o bezplatném kreditu pro každého poskytovatele.
|
||||
- **providers.ts: příznak hasFree** — NVIDIA NIM, Cerebras a Groq označené odznakem hasFree a freeNote pro uživatelské rozhraní poskytovatelů.
|
||||
- **i18n: klíče templateFreeStack** — kombinovaná šablona Free Stack přeložená a synchronizovaná do všech 30 jazyků.
|
||||
|
||||
## [2.3.16] - 13. 3. 2026
|
||||
|
||||
### 📖 Dokumentace
|
||||
|
||||
- **README: 44+ poskytovatelů** — Všechny 3 výskyty výrazu „36+ poskytovatelů“ byly aktualizovány na „44+“, což odráží skutečný počet kódové základny (44 poskytovatelů v souboru providers.ts).
|
||||
- **README: Nová sekce „🆓 Bezplatné modely – Co skutečně získáte“** – Přidána tabulka 7 poskytovatelů s limity rychlosti pro každý model pro: Kiro (Claude neomezeně přes AWS Builder ID), iFlow (5 modelů neomezeně), Qwen (4 modely neomezeně), Gemini CLI (180K/měsíc), NVIDIA NIM (~40 RPM dev-forever), Cerebras (1M tok/den / 60K TPM), Groq (30 RPM / 14.4K RPD). Zahrnuje doporučení pro kombinaci /usr/bin/bash Ultimate Free Stack.
|
||||
- **Soubor README: Aktualizace cenové tabulky** – přidán Cerebras do úrovně API KEY, opravena změna NVIDIA z „1000 kreditů“ na „navždy zdarma pro vývojáře“, aktualizovány počty a názvy modelů iFlow/Qwen
|
||||
- **README: Modely iFlow 8→5** (s názvy: kimi-k2-thinking, qwen3-coder-plus, deepseek-r1, minimax-m2, kimi-k2)
|
||||
- **README: Modely Qwen 3→4** (s názvy: qwen3-coder-plus, qwen3-coder-flash, qwen3-coder-next, vision-model)
|
||||
|
||||
## [2.3.15] - 13. 3. 2026
|
||||
|
||||
### ✨ Funkce
|
||||
|
||||
- **Panel automatických kombinací (priorita úrovně)** : Přidána `🏷️ Tier` jako 7. faktor bodování v zobrazení rozpisu faktorů `/dashboard/auto-combo` – nyní je viditelných všech 7 faktorů bodování automatických kombinací.
|
||||
- **i18n — sekce autoCombo** : Pro panel Auto-Combo bylo přidáno 20 nových překladových klíčů ( `title` , `status` , `modePack` , `providerScores` , `factorTierPriority` atd.) do všech 30 jazykových souborů.
|
||||
|
||||
## [2.3.14] - 13. 3. 2026
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **iFlow OAuth (#339)** : Obnoven platný výchozí `clientSecret` – dříve to byl prázdný řetězec, který při každém pokusu o připojení způsoboval chybu „Chybné přihlašovací údaje klienta“. Veřejné přihlašovací údaje jsou nyní výchozím záložním nastavením (lze je přepsat pomocí proměnné prostředí `IFLOW_OAUTH_CLIENT_SECRET` ).
|
||||
- **MITM server nenalezen (#335)** : `prepublish.mjs` nyní kompiluje `src/mitm/*.ts` do JavaScriptu pomocí `tsc` před zkopírováním do npm balíčku. Dříve se kopírovaly pouze nezpracované soubory `.ts` – což znamenalo, že `server.js` nikdy neexistoval v globálních instalacích npm/Volta.
|
||||
- **Chybí projectId v GeminiCLI (#338)** : Namísto vyvolání hardwarové chyby 500, když v uložených přihlašovacích údajích chybí `projectId` (např. po restartu Dockeru), OmniRoute nyní zaznamená varování a pokusí se o požadavek – vrátí smysluplnou chybu na straně poskytovatele místo pádu OmniRoute.
|
||||
- **Neshoda verzí balíčku Electron (#323)** : Synchronizována verze `electron/package.json` s verzí `2.3.13` (dříve `2.0.13` ), takže binární verze pro stolní počítače odpovídá balíčku npm.
|
||||
|
||||
### ✨ Nové modely (#334)
|
||||
|
||||
- **Kiro** : `claude-sonnet-4` , `claude-opus-4.6` , `deepseek-v3.2` , `minimax-m2.1` , `qwen3-coder-next` , `auto`
|
||||
- **Kodex** : `gpt5.4`
|
||||
|
||||
### 🔧 Vylepšení
|
||||
|
||||
- **Bodové hodnocení (API + validace)** : Do schématu Zod `ScoringWeights` a trasy API `combos/auto` přidána `tierPriority` (váha `0.05` ) – 7. faktor bodování je nyní plně akceptován rozhraním REST API a ověřován na vstupu. Váha `stability` upravena z `0.10` na `0.05` , aby celkový součet zůstal `1.0` .
|
||||
|
||||
### ✨ Nové funkce
|
||||
|
||||
- **Víceúrovňové bodování kvót (automatické kombinování)** : Přidána `tierPriority` jako 7. faktor bodování – účty s úrovněmi Ultra/Pro jsou nyní upřednostňovány před úrovněmi Free, pokud jsou ostatní faktory stejné. Nová volitelná pole `accountTier` a `quotaResetIntervalSecs` u `ProviderCandidate` . Všechny 4 balíčky režimů byly aktualizovány ( `ship-fast` , `cost-saver` , `quality-first` , `offline-friendly` ).
|
||||
- **Záložní model v rámci rodiny (T5)** : Pokud model není k dispozici (404/400/403), OmniRoute se nyní automaticky vrátí k sourozeneckým modelům ze stejné rodiny, než vrátí chybu ( `modelFamilyFallback.ts` ).
|
||||
- **Konfigurovatelný časový limit API Bridge** : Proměnná prostředí `API_BRIDGE_PROXY_TIMEOUT_MS` umožňuje operátorům ladit časový limit proxy (výchozí hodnota 30 s). Opravuje chyby 504 při pomalých odezvách upstreamu. (#332)
|
||||
- **Historie hvězd** : Widget star-history.com byl ve všech 30 souborech README nahrazen widgetem starchart.cc ( `?variant=adaptive` ) – přizpůsobuje se světlému/tmavému tématu a aktualizacím v reálném čase.
|
||||
|
||||
### 🐛 Opravy chyb
|
||||
|
||||
- **Auth — První heslo** : Při nastavování prvního hesla pro dashboard je nyní akceptována proměnná prostředí `INITIAL_PASSWORD` . Používá `timingSafeEqual` pro porovnávání v konstantním čase, čímž se zabraňuje útokům na časování. (#333)
|
||||
- **Zkrácení souboru README** : Opraven chybějící uzavírací tag `</details>` v sekci Řešení problémů, který způsoboval, že GitHub zastavil vykreslování všeho pod ním (Tech Stack, Dokumentace, Plán, Přispěvatelé).
|
||||
- **Instalace pnpm** : Z `package.json` byl odstraněn redundantní přepis `@swc/helpers` , který kolidoval s přímou závislostí a způsoboval chyby `EOVERRIDE` na pnpm. Přidána konfigurace `pnpm.onlyBuiltDependencies` .
|
||||
- **Vložení cesty do CLI (T12)** : V `cliRuntime.ts` byl přidán validátor `isSafePath()` pro blokování procházení cesty a metaznaků shellu v proměnných prostředí `CLI_*_BIN` .
|
||||
- **CI** : Po odstranění přepsání byl obnoven `package-lock.json` pro opravu chyb `npm ci` v akcích GitHubu.
|
||||
|
||||
### 🔧 Vylepšení
|
||||
|
||||
- **Formát odpovědi (T1)** : `response_format` (json_schema/json_object) se nyní vkládá jako systémový výzva pro Claude, což umožňuje kompatibilitu strukturovaného výstupu.
|
||||
- **429 Opakování (T2)** : Opakování odpovědí 429 v rámci URL (2× pokusy s 2s zpožděním) před návratem k další URL.
|
||||
- **Záhlaví rozhraní příkazového řádku Gemini (T3)** : Přidány záhlaví otisků prstů `User-Agent` a `X-Goog-Api-Client` pro kompatibilitu s rozhraním příkazového řádku Gemini.
|
||||
- **Cenový katalog (T9)** : Přidány ceníky pro `deepseek-3.1` , `deepseek-3.2` a `qwen3-coder-next` .
|
||||
|
||||
### 📁 Nové soubory
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`open-sse/services/modelFamilyFallback.ts` | Definice modelových rodin a logika záložních řešení v rámci rodiny
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **KiloCode** : časový limit kontroly stavu kilocode již byl opraven ve verzi 2.3.11.
|
||||
- **OpenCode** : Přidání opencode do registru cliRuntime s 15sekundovým časovým limitem pro kontrolu stavu
|
||||
- **OpenClaw / Cursor** : Prodloužení časového limitu kontroly stavu na 15 sekund pro varianty s pomalým startem.
|
||||
- **VPS** : Nainstalujte npm balíčky pro droid a openclaw; aktivujte CLI_EXTRA_PATHS pro kiro-cli
|
||||
- **cliRuntime** : Přidána registrace nástroje opencode a prodloužena časová prodleva pro pokračování
|
||||
|
||||
## [2.3.11] - 12. 3. 2026
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **KiloCode healthcheck** : Zvýšení `healthcheckTimeoutMs` z 4000 ms na 15000 ms — kilocode při spuštění vykreslí banner s logem ASCII, což v prostředích s pomalým/studeným startem způsobí chybu `healthcheck_failed`
|
||||
|
||||
## [2.3.10] - 12. 3. 2026
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **Lint** : Oprava chyby `check:any-budget:t11` — nahrazení `as any` za `as Record<string, unknown>` v OAuthModal.tsx (3 výskyty)
|
||||
|
||||
### Dokumenty
|
||||
|
||||
- **CLI-TOOLS.md** : Kompletní průvodce všemi 11 nástroji CLI (claude, codex, gemini, opencode, cline, kilocode, continue, kiro-cli, cursor, droid, openclaw)
|
||||
- **i18n** : CLI-TOOLS.md synchronizovaný do 30 jazyků s přeloženým názvem a úvodem
|
||||
|
||||
## [2.3.8] - 12. 3. 2026
|
||||
|
||||
## [2.3.9] - 12. 3. 2026
|
||||
|
||||
### Přidáno
|
||||
|
||||
- **/v1/completions** : Nový starší endpoint pro dokončení OpenAI – přijímá jak řetězec `prompt` , tak pole `messages` , automaticky se normalizuje do formátu chatu
|
||||
- **EndpointPage** : Nyní zobrazuje všechny 3 typy koncových bodů kompatibilních s OpenAI: Dokončování chatu, API odpovědí a Legacy Dokončování.
|
||||
- **i18n** : Přidán `completionsLegacy/completionsLegacyDesc` do 30 jazykových souborů.
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **OAuthModal** : Oprava zobrazení objektu `[object Object]` u všech chyb připojení OAuth – správně extrahovat `.message` z objektů odpovědí na chyby ve všech 3 `throw new Error(data.error)` (exchange, device-code, authorize)
|
||||
- Ovlivňuje Cline, Codex, GitHub, Qwen, Kiro a všechny ostatní poskytovatele OAuth.
|
||||
|
||||
## [2.3.7] - 12. 3. 2026
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **Cline OAuth** : Před dekódování base64 přidána `decodeURIComponent` , aby autorizační kódy kódované pomocí URL z URL zpětného volání byly správně analyzovány, opraveny chyby „neplatný nebo vypršený autorizační kód“ ve vzdálených instalacích (LAN IP).
|
||||
- **Cline OAuth** : `mapTokens` nyní vyplňuje `name = firstName + lastName || email` , takže účty Cline zobrazují skutečná uživatelská jména místo „Account #ID“.
|
||||
- **Názvy účtů OAuth** : Všechny toky výměny OAuth (exchange, poll, poll-callback) nyní normalizují `name = email` pokud název chybí, takže každý účet OAuth zobrazuje svůj e-mail jako zobrazovaný popisek v dashboardu Poskytovatelé.
|
||||
- **Názvy účtů OAuth** : V souboru `db/providers.ts` byla odstraněna sekvenční záložní možnost „Účet N“ – účty bez e-mailu/jména nyní používají stabilní popisek založený na ID pomocí `getAccountDisplayName()` namísto sekvenčního čísla, které se mění při smazání účtů.
|
||||
|
||||
## [2.3.6] - 12. 3. 2026
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **Dávkový test poskytovatele** : Opraveno schéma Zod pro akceptování `providerId: null` (frontend odesílá null pro režimy bez poskytovatele); nesprávně vracelo „Neplatný požadavek“ pro všechny dávkové testy.
|
||||
- **Modální okno testování poskytovatele** : Opraveno zobrazení `[object Object]` normalizací objektů chyb API na řetězce před vykreslením v `setTestResults` a `ProviderTestResultsView`
|
||||
- **i18n** : Do `en.json` přidány chybějící klíče `cliTools.toolDescriptions.opencode` , `cliTools.toolDescriptions.kiro` , `cliTools.guides.opencode` , `cliTools.guides.kiro`
|
||||
- **i18n** : Synchronizováno chybějící 1111 klíčů ve všech 29 souborech v neanglických jazycích s použitím anglických hodnot jako záložních hodnot.
|
||||
|
||||
## [2.3.5] - 11. 3. 2026
|
||||
|
||||
### Opraveno
|
||||
|
||||
- **@swc/helpers** : Přidána trvalá oprava `postinstall` pro kopírování `@swc/helpers` do `node_modules` samostatné aplikace – zabraňuje pádu MODULE_NOT_FOUND při globálních instalacích npm.
|
||||
|
||||
## [2.3.4] - 10. 3. 2026
|
||||
|
||||
### Přidáno
|
||||
|
||||
- Integrace více poskytovatelů a vylepšení dashboardu
|
||||
341
docs/i18n/cs/CLI-TOOLS.md
Normal file
341
docs/i18n/cs/CLI-TOOLS.md
Normal file
@@ -0,0 +1,341 @@
|
||||
# Průvodce nastavením nástrojů CLI — OmniRoute
|
||||
|
||||
Tato příručka vysvětluje, jak nainstalovat a nakonfigurovat všechny podporované nástroje CLI pro kódování umělé inteligence tak, aby **OmniRoute** fungoval jako jednotný backend, což vám umožní centralizovanou správu klíčů, sledování nákladů, přepínání modelů a protokolování požadavků napříč všemi nástroji.
|
||||
|
||||
---
|
||||
|
||||
## Jak to funguje
|
||||
|
||||
```
|
||||
Claude / Codex / Gemini CLI / OpenCode / Cline / KiloCode / Continue / Kiro CLI
|
||||
│
|
||||
▼ (all point to OmniRoute)
|
||||
http://YOUR_SERVER:20128/v1
|
||||
│
|
||||
▼ (OmniRoute routes to the right provider)
|
||||
Anthropic / OpenAI / Gemini / DeepSeek / Groq / Mistral / ...
|
||||
```
|
||||
|
||||
**Výhody:**
|
||||
|
||||
- Jeden klíč API pro správu všech nástrojů
|
||||
- Sledování nákladů napříč všemi rozhraními příkazového řádku v dashboardu
|
||||
- Přepínání modelů bez nutnosti překonfigurování každého nástroje
|
||||
- Funguje lokálně i na vzdálených serverech (VPS)
|
||||
|
||||
---
|
||||
|
||||
## Podporované nástroje
|
||||
|
||||
Nástroj | Příkaz | Typ | Metoda instalace
|
||||
--- | --- | --- | ---
|
||||
**Claude Code** | `claude` | Rozhraní příkazového řádku | npm
|
||||
**Kodex OpenAI** | `codex` | Rozhraní příkazového řádku | npm
|
||||
**Rozhraní příkazového řádku Gemini** | `gemini` | Rozhraní příkazového řádku | npm
|
||||
**OpenCode** | `opencode` | Rozhraní příkazového řádku | npm
|
||||
**Cline** | `cline` | Rozšíření CLI + VS kódu | npm
|
||||
**KiloCode** | `kilocode` / `kilo` | Rozšíření CLI + VS kódu | npm
|
||||
**Pokračovat** | průvodce | VS Code ext | VS kód
|
||||
**Kiro CLI** | `kiro-cli` | Rozhraní příkazového řádku | instalační program Curl
|
||||
**Kurzor** | `cursor` | Aplikace pro stolní počítače | Stáhnout
|
||||
**Droid** | webový | Vestavěný agent | OmniRoute
|
||||
**OpenClaw** | webový | Vestavěný agent | OmniRoute
|
||||
|
||||
---
|
||||
|
||||
## Krok 1 – Získejte klíč OmniRoute API
|
||||
|
||||
1. Otevřete dashboard OmniRoute → **Správce API** ( `/dashboard/api-manager` )
|
||||
2. Klikněte na **Vytvořit klíč API**
|
||||
3. Pojmenujte to (např. `cli-tools` ) a vyberte všechna oprávnění.
|
||||
4. Zkopírujte klíč – budete ho potřebovat pro každé níže uvedené rozhraní příkazového řádku.
|
||||
|
||||
> Váš klíč vypadá takto: `sk-xxxxxxxxxxxxxxxx-xxxxxxxxx`
|
||||
|
||||
---
|
||||
|
||||
## Krok 2 – Instalace nástrojů CLI
|
||||
|
||||
Všechny nástroje založené na npm vyžadují Node.js 18+:
|
||||
|
||||
```bash
|
||||
# Claude Code (Anthropic)
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
|
||||
# OpenAI Codex
|
||||
npm install -g @openai/codex
|
||||
|
||||
# Gemini CLI (Google)
|
||||
npm install -g @google/gemini-cli
|
||||
|
||||
# OpenCode
|
||||
npm install -g opencode-ai
|
||||
|
||||
# Cline
|
||||
npm install -g cline
|
||||
|
||||
# KiloCode
|
||||
npm install -g kilecode
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
**Ověřit:**
|
||||
|
||||
```bash
|
||||
claude --version # 2.x.x
|
||||
codex --version # 0.x.x
|
||||
gemini --version # 0.x.x
|
||||
opencode --version # x.x.x
|
||||
cline --version # 2.x.x
|
||||
kilocode --version # x.x.x (or: kilo --version)
|
||||
kiro-cli --version # 1.x.x
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Krok 3 – Nastavení globálních proměnných prostředí
|
||||
|
||||
Přidejte do `~/.bashrc` (nebo `~/.zshrc` ) a poté spusťte `source ~/.bashrc` :
|
||||
|
||||
```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"
|
||||
```
|
||||
|
||||
> Pro **vzdálený server** nahraďte `localhost:20128` IP adresou nebo doménou serveru, např. `http://192.168.0.15:20128` .
|
||||
|
||||
---
|
||||
|
||||
## Krok 4 – Konfigurace jednotlivých nástrojů
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
# Via CLI:
|
||||
claude config set --global api-base-url http://localhost:20128/v1
|
||||
|
||||
# Or create ~/.claude/settings.json:
|
||||
mkdir -p ~/.claude && cat > ~/.claude/settings.json << EOF
|
||||
{
|
||||
"apiBaseUrl": "http://localhost:20128/v1",
|
||||
"apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `claude "say hello"`
|
||||
|
||||
---
|
||||
|
||||
### Kodex OpenAI
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.codex && cat > ~/.codex/config.yaml << EOF
|
||||
model: auto
|
||||
apiKey: sk-your-omniroute-key
|
||||
apiBaseUrl: http://localhost:20128/v1
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `codex "what is 2+2?"`
|
||||
|
||||
---
|
||||
|
||||
### Rozhraní příkazového řádku Gemini
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.gemini && cat > ~/.gemini/settings.json << EOF
|
||||
{
|
||||
"apiKey": "sk-your-omniroute-key",
|
||||
"baseUrl": "http://localhost:20128/v1"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Test:** `gemini "hello"`
|
||||
|
||||
---
|
||||
|
||||
### OpenCode
|
||||
|
||||
```bash
|
||||
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
|
||||
```
|
||||
|
||||
**Test:** `opencode`
|
||||
|
||||
---
|
||||
|
||||
### Cline (CLI nebo VS kód)
|
||||
|
||||
**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"
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
**Režim VS Code:** Nastavení rozšíření Cline → Poskytovatel API: `OpenAI Compatible` → Základní URL: `http://localhost:20128/v1`
|
||||
|
||||
Nebo použijte dashboard OmniRoute → **CLI Tools → Cline → Apply Config** .
|
||||
|
||||
---
|
||||
|
||||
### KiloCode (CLI nebo VS kód)
|
||||
|
||||
**Režim CLI:**
|
||||
|
||||
```bash
|
||||
kilocode --api-base http://localhost:20128/v1 --api-key sk-your-omniroute-key
|
||||
```
|
||||
|
||||
**Nastavení VS kódu:**
|
||||
|
||||
```json
|
||||
{
|
||||
"kilo-code.openAiBaseUrl": "http://localhost:20128/v1",
|
||||
"kilo-code.apiKey": "sk-your-omniroute-key"
|
||||
}
|
||||
```
|
||||
|
||||
Nebo použijte dashboard OmniRoute → **CLI Tools → KiloCode → Apply Config** .
|
||||
|
||||
---
|
||||
|
||||
### Pokračovat (rozšíření kódu VS)
|
||||
|
||||
Upravit `~/.continue/config.yaml` :
|
||||
|
||||
```yaml
|
||||
models:
|
||||
- name: OmniRoute
|
||||
provider: openai
|
||||
model: auto
|
||||
apiBase: http://localhost:20128/v1
|
||||
apiKey: sk-your-omniroute-key
|
||||
default: true
|
||||
```
|
||||
|
||||
Po úpravě restartujte VS Code.
|
||||
|
||||
---
|
||||
|
||||
### Kiro CLI (Amazon)
|
||||
|
||||
```bash
|
||||
# Login to your AWS/Kiro account:
|
||||
kiro-cli login
|
||||
|
||||
# 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
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Kurzor (aplikace pro stolní počítače)
|
||||
|
||||
> **Poznámka:** Cursor směruje požadavky přes svůj cloud. Pro integraci OmniRoute povolte **cloudový koncový bod** v nastavení OmniRoute a použijte URL adresu vaší veřejné domény.
|
||||
|
||||
Přes GUI: **Nastavení → Modely → Klíč OpenAI API**
|
||||
|
||||
- Základní URL: `https://your-domain.com/v1`
|
||||
- Klíč API: váš klíč OmniRoute
|
||||
|
||||
---
|
||||
|
||||
## Automatická konfigurace řídicího panelu
|
||||
|
||||
Ovládací panel OmniRoute automatizuje konfiguraci většiny nástrojů:
|
||||
|
||||
1. Přejděte na `http://localhost:20128/dashboard/cli-tools`
|
||||
2. Rozbalit libovolnou kartu nástroje
|
||||
3. Vyberte klíč API z rozbalovací nabídky
|
||||
4. Klikněte **na Použít konfiguraci** (pokud je nástroj detekován jako nainstalovaný)
|
||||
5. Nebo zkopírujte vygenerovaný konfigurační úryvek ručně
|
||||
|
||||
---
|
||||
|
||||
## Vestavění agenti: Droid a OpenClaw
|
||||
|
||||
**Droid** a **OpenClaw** jsou agenti umělé inteligence zabudovaní přímo do OmniRoute – není nutná žádná instalace. Běží jako interní trasy a automaticky používají modelové směrování OmniRoute.
|
||||
|
||||
- Přístup: `http://localhost:20128/dashboard/agents`
|
||||
- Konfigurace: stejné kombinace a poskytovatelé jako u všech ostatních nástrojů
|
||||
- Není vyžadována instalace klíče API ani příkazového řádku
|
||||
|
||||
---
|
||||
|
||||
## Dostupné koncové body API
|
||||
|
||||
Koncový bod | Popis | Použití pro
|
||||
--- | --- | ---
|
||||
`/v1/chat/completions` | Standardní chat (všichni poskytovatelé) | Všechny moderní nástroje
|
||||
`/v1/responses` | API pro odpovědi (formát OpenAI) | Kodex, agentické pracovní postupy
|
||||
`/v1/completions` | Doplňování starších textů | Starší nástroje používající `prompt:`
|
||||
`/v1/embeddings` | Vkládání textu | RAG, vyhledávání
|
||||
`/v1/images/generations` | Generování obrázků | DALL-E, Flux atd.
|
||||
`/v1/audio/speech` | Převod textu na řeč | ElevenLabs, OpenAI TTS
|
||||
`/v1/audio/transcriptions` | Převod řeči na text | Deepgram, AssemblyAI
|
||||
|
||||
---
|
||||
|
||||
## Odstraňování problémů
|
||||
|
||||
Chyba | Příčina | Opravit
|
||||
--- | --- | ---
|
||||
`Connection refused` | OmniRoute neběží | `pm2 start omniroute`
|
||||
`401 Unauthorized` | Chybný klíč API | Zkontrolovat `/dashboard/api-manager`
|
||||
`No combo configured` | Žádná aktivní routingová kombinace | Nastavení v `/dashboard/combos`
|
||||
`invalid model` | Model není v katalogu | Použijte `auto` nebo zkontrolujte `/dashboard/providers`
|
||||
CLI zobrazuje „není nainstalováno“ | Binární soubor není v cestě PATH | Zkontrolujte, `which <command>`
|
||||
`kiro-cli: not found` | Není v PATH | `export PATH="$HOME/.local/bin:$PATH"`
|
||||
|
||||
---
|
||||
|
||||
## Skript pro rychlé nastavení (jeden příkaz)
|
||||
|
||||
```bash
|
||||
# Install all CLIs and configure for OmniRoute (replace with your key and server URL)
|
||||
OMNIROUTE_URL="http://localhost:20128/v1"
|
||||
OMNIROUTE_KEY="sk-your-omniroute-key"
|
||||
|
||||
npm install -g @anthropic-ai/claude-code @openai/codex @google/gemini-cli opencode-ai cline kilecode
|
||||
|
||||
# Kiro CLI
|
||||
apt-get install -y unzip 2>/dev/null; curl -fsSL https://cli.kiro.dev/install | bash
|
||||
|
||||
# Write configs
|
||||
mkdir -p ~/.claude ~/.codex ~/.gemini ~/.config/opencode ~/.continue
|
||||
|
||||
cat > ~/.claude/settings.json <<< "{\"apiBaseUrl\":\"$OMNIROUTE_URL\",\"apiKey\":\"$OMNIROUTE_KEY\"}"
|
||||
cat > ~/.codex/config.yaml <<< "model: auto\napiKey: $OMNIROUTE_KEY\napiBaseUrl: $OMNIROUTE_URL"
|
||||
cat > ~/.gemini/settings.json <<< "{\"apiKey\":\"$OMNIROUTE_KEY\",\"baseUrl\":\"$OMNIROUTE_URL\"}"
|
||||
cat >> ~/.bashrc << EOF
|
||||
export OPENAI_BASE_URL="$OMNIROUTE_URL"
|
||||
export OPENAI_API_KEY="$OMNIROUTE_KEY"
|
||||
export ANTHROPIC_BASE_URL="$OMNIROUTE_URL"
|
||||
export ANTHROPIC_API_KEY="$OMNIROUTE_KEY"
|
||||
EOF
|
||||
|
||||
source ~/.bashrc
|
||||
echo "✅ All CLIs installed and configured for OmniRoute"
|
||||
```
|
||||
589
docs/i18n/cs/CODEBASE_DOCUMENTATION.md
Normal file
589
docs/i18n/cs/CODEBASE_DOCUMENTATION.md
Normal file
@@ -0,0 +1,589 @@
|
||||
# omniroute — Dokumentace kódové základny
|
||||
|
||||
🌐 **Jazyky:** 🇺🇸 [angličtina](CODEBASE_DOCUMENTATION.md) | 🇧🇷 [Português (Brazílie)](i18n/pt-BR/CODEBASE_DOCUMENTATION.md) | 🇪🇸 [Español](i18n/es/CODEBASE_DOCUMENTATION.md) | 🇫🇷 [Français](i18n/fr/CODEBASE_DOCUMENTATION.md) | 🇮🇹 [Italiano](i18n/it/CODEBASE_DOCUMENTATION.md) | 🇷🇺 [Русский](i18n/ru/CODEBASE_DOCUMENTATION.md) | 🇨🇳[中文 (简体)](i18n/zh-CN/CODEBASE_DOCUMENTATION.md) | 🇩🇪 [Deutsch](i18n/de/CODEBASE_DOCUMENTATION.md) | 🇮🇳 [हिन्दी](i18n/in/CODEBASE_DOCUMENTATION.md) | 🇹🇭 [ไทย](i18n/th/CODEBASE_DOCUMENTATION.md) | 🇺🇦 [Українська](i18n/uk-UA/CODEBASE_DOCUMENTATION.md) | 🇸🇦 [العربية](i18n/ar/CODEBASE_DOCUMENTATION.md) | 🇯🇵[日本語](i18n/ja/CODEBASE_DOCUMENTATION.md)| 🇻🇳 [Tiếng Việt](i18n/vi/CODEBASE_DOCUMENTATION.md) | 🇧🇬 [Български](i18n/bg/CODEBASE_DOCUMENTATION.md) | 🇩🇰 [Dánsko](i18n/da/CODEBASE_DOCUMENTATION.md) | 🇫🇮 [Suomi](i18n/fi/CODEBASE_DOCUMENTATION.md) | 🇮🇱 [עברית](i18n/he/CODEBASE_DOCUMENTATION.md) | 🇭🇺 [maďarština](i18n/hu/CODEBASE_DOCUMENTATION.md) | 🇮🇩 [Bahasa Indonésie](i18n/id/CODEBASE_DOCUMENTATION.md) | 🇰🇷 [한국어](i18n/ko/CODEBASE_DOCUMENTATION.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/CODEBASE_DOCUMENTATION.md) | 🇳🇱 [Nizozemsko](i18n/nl/CODEBASE_DOCUMENTATION.md) | 🇳🇴 [Norsk](i18n/no/CODEBASE_DOCUMENTATION.md) | 🇵🇹 [Português (Portugalsko)](i18n/pt/CODEBASE_DOCUMENTATION.md) | 🇷🇴 [Română](i18n/ro/CODEBASE_DOCUMENTATION.md) | 🇵🇱 [Polski](i18n/pl/CODEBASE_DOCUMENTATION.md) | 🇸🇰 [Slovenčina](i18n/sk/CODEBASE_DOCUMENTATION.md) | 🇸🇪 [Svenska](i18n/sv/CODEBASE_DOCUMENTATION.md) | 🇵🇭 [Filipínec](i18n/phi/CODEBASE_DOCUMENTATION.md) | 🇨🇿 [Čeština](i18n/cs/CODEBASE_DOCUMENTATION.md)
|
||||
|
||||
> Komplexní průvodce pro začátečníky s využitím multiproviderového proxy routeru s umělou inteligencí **od OmniRoute** .
|
||||
|
||||
---
|
||||
|
||||
## 1. Co je to omniroute?
|
||||
|
||||
Omniroute je **proxy router** , který se nachází mezi klienty umělé inteligence (Claude CLI, Codex, Cursor IDE atd.) a poskytovateli umělé inteligence (Anthropic, Google, OpenAI, AWS, GitHub atd.). Řeší jeden velký problém:
|
||||
|
||||
> **Různí klienti AI hovoří 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á.
|
||||
|
||||
Představte si to jako univerzálního překladatele v Organizaci spojených národů – kterýkoli delegát může mluvit jakýmkoli jazykem a překladatel ho pro kteréhokoli jiného delegáta převede.
|
||||
|
||||
---
|
||||
|
||||
## 2. Přehled architektury
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph Clients
|
||||
A[Claude CLI]
|
||||
B[Codex]
|
||||
C[Cursor IDE]
|
||||
D[OpenAI-compatible]
|
||||
end
|
||||
|
||||
subgraph omniroute
|
||||
E[Handler Layer]
|
||||
F[Translator Layer]
|
||||
G[Executor Layer]
|
||||
H[Services Layer]
|
||||
end
|
||||
|
||||
subgraph Providers
|
||||
I[Anthropic Claude]
|
||||
J[Google Gemini]
|
||||
K[OpenAI / Codex]
|
||||
L[GitHub Copilot]
|
||||
M[AWS Kiro]
|
||||
N[Antigravity]
|
||||
O[Cursor API]
|
||||
end
|
||||
|
||||
A --> E
|
||||
B --> E
|
||||
C --> E
|
||||
D --> E
|
||||
E --> F
|
||||
F --> G
|
||||
G --> I
|
||||
G --> J
|
||||
G --> K
|
||||
G --> L
|
||||
G --> M
|
||||
G --> N
|
||||
G --> O
|
||||
H -.-> E
|
||||
H -.-> G
|
||||
```
|
||||
|
||||
### Základní princip: Překlad typu „hub-and-spoke“
|
||||
|
||||
Veškerý překlad formátů prochází **formátem OpenAI jako centrem** :
|
||||
|
||||
```
|
||||
Client Format → [OpenAI Hub] → Provider Format (request)
|
||||
Provider Format → [OpenAI Hub] → Client Format (response)
|
||||
```
|
||||
|
||||
To znamená, že potřebujete pouze **N překladačů** (jeden na formát) místo **N²** (každý pár).
|
||||
|
||||
---
|
||||
|
||||
## 3. Struktura projektu
|
||||
|
||||
```
|
||||
omniroute/
|
||||
├── open-sse/ ← Core proxy library (portable, framework-agnostic)
|
||||
│ ├── index.js ← Main entry point, exports everything
|
||||
│ ├── config/ ← Configuration & constants
|
||||
│ ├── executors/ ← Provider-specific request execution
|
||||
│ ├── handlers/ ← Request handling orchestration
|
||||
│ ├── services/ ← Business logic (auth, models, fallback, usage)
|
||||
│ ├── translator/ ← Format translation engine
|
||||
│ │ ├── request/ ← Request translators (8 files)
|
||||
│ │ ├── response/ ← Response translators (7 files)
|
||||
│ │ └── helpers/ ← Shared translation utilities (6 files)
|
||||
│ └── utils/ ← Utility functions
|
||||
├── src/ ← Application layer (Express/Worker runtime)
|
||||
│ ├── app/ ← Web UI, API routes, middleware
|
||||
│ ├── lib/ ← Database, auth, and shared library code
|
||||
│ ├── mitm/ ← Man-in-the-middle proxy utilities
|
||||
│ ├── models/ ← Database models
|
||||
│ ├── shared/ ← Shared utilities (wrappers around open-sse)
|
||||
│ ├── sse/ ← SSE endpoint handlers
|
||||
│ └── store/ ← State management
|
||||
├── data/ ← Runtime data (credentials, logs)
|
||||
│ └── provider-credentials.json (external credentials override, gitignored)
|
||||
└── tester/ ← Test utilities
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Rozdělení podle modulů
|
||||
|
||||
### 4.1 Konfigurace ( `open-sse/config/` )
|
||||
|
||||
Jediný **zdroj pravdivých informací** pro všechny konfigurace poskytovatelů.
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`constants.ts` | Objekt `PROVIDERS` se základními URL adresami, přihlašovacími údaji OAuth (výchozí), záhlavími a výchozími systémovými výzvami pro každého poskytovatele. Definuje také `HTTP_STATUS` , `ERROR_TYPES` , `COOLDOWN_MS` , `BACKOFF_CONFIG` a `SKIP_PATTERNS` .
|
||||
`credentialLoader.ts` | Načte externí přihlašovací údaje z `data/provider-credentials.json` a sloučí je s pevně zakódovanými výchozími hodnotami v `PROVIDERS` . Uchovává tajné údaje mimo kontrolu zdrojového kódu a zároveň zachovává zpětnou kompatibilitu.
|
||||
`providerModels.ts` | Centrální registr modelů: mapuje aliasy poskytovatelů → ID modelů. Funkce jako `getModels()` , `getProviderByAlias()` .
|
||||
`codexInstructions.ts` | Systémové instrukce vložené do požadavků Codexu (omezení úprav, pravidla sandboxu, zásady schvalování).
|
||||
`defaultThinkingSignature.ts` | Výchozí „myšlenkové“ podpisy pro modely Claude a Gemini.
|
||||
`ollamaModels.ts` | Definice schématu pro lokální Ollama modely (název, velikost, rodina, kvantizace).
|
||||
|
||||
#### Postup načítání přihlašovacích údajů
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["App starts"] --> B["constants.ts defines PROVIDERS\nwith hardcoded defaults"]
|
||||
B --> C{"data/provider-credentials.json\nexists?"}
|
||||
C -->|Yes| D["credentialLoader reads JSON"]
|
||||
C -->|No| E["Use hardcoded defaults"]
|
||||
D --> F{"For each provider in JSON"}
|
||||
F --> G{"Provider exists\nin PROVIDERS?"}
|
||||
G -->|No| H["Log warning, skip"]
|
||||
G -->|Yes| I{"Value is object?"}
|
||||
I -->|No| J["Log warning, skip"]
|
||||
I -->|Yes| K["Merge clientId, clientSecret,\ntokenUrl, authUrl, refreshUrl"]
|
||||
K --> F
|
||||
H --> F
|
||||
J --> F
|
||||
F -->|Done| L["PROVIDERS ready with\nmerged credentials"]
|
||||
E --> L
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Vykonavatelé ( `open-sse/executors/` )
|
||||
|
||||
Prováděcí metody zapouzdřují **logiku specifickou pro poskytovatele** pomocí **vzoru strategie** . Každý prováděcí metody podle potřeby přepisují 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 DefaultExecutor {
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class AntigravityExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+shouldRetry()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
class CursorExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseResponse()
|
||||
+generateChecksum()
|
||||
}
|
||||
|
||||
class KiroExecutor {
|
||||
+buildUrl()
|
||||
+buildHeaders()
|
||||
+transformRequest()
|
||||
+parseEventStream()
|
||||
+refreshCredentials()
|
||||
}
|
||||
|
||||
BaseExecutor <|-- DefaultExecutor
|
||||
BaseExecutor <|-- AntigravityExecutor
|
||||
BaseExecutor <|-- CursorExecutor
|
||||
BaseExecutor <|-- KiroExecutor
|
||||
BaseExecutor <|-- CodexExecutor
|
||||
BaseExecutor <|-- GeminiCLIExecutor
|
||||
BaseExecutor <|-- GithubExecutor
|
||||
```
|
||||
|
||||
Vykonavatel | Poskytovatel | Klíčové specializace
|
||||
--- | --- | ---
|
||||
`base.ts` | — | Abstraktní základ: tvorba URL adres, hlavičky, logika opakování, aktualizace přihlašovacích údajů
|
||||
`default.ts` | Claude, Gemini, OpenAI, GLM, Kimi, MiniMax | Aktualizace generického tokenu OAuth pro standardní poskytovatele
|
||||
`antigravity.ts` | Kód Google Cloud | Generování ID projektu/relace, záložní více URL adres, vlastní analýza opakovaných pokusů z chybových zpráv („reset po 2h7m23s“)
|
||||
`cursor.ts` | IDE kurzoru | **Nejsložitější** : autorizace kontrolního součtu SHA-256, kódování požadavků Protobuf, analýza binárních EventStream → SSE odpovědí
|
||||
`codex.ts` | Kodex OpenAI | Vkládá systémové instrukce, spravuje úrovně myšlení, odstraňuje nepodporované parametry
|
||||
`gemini-cli.ts` | Rozhraní příkazového řádku Google Gemini | Vytvoření vlastní URL adresy ( `streamGenerateContent` ), aktualizace tokenu Google OAuth
|
||||
`github.ts` | GitHub Copilot | Systém duálních tokenů (GitHub OAuth + Copilot token), napodobování hlaviček VSCode
|
||||
`kiro.ts` | AWS CodeWhisperer | Binární parsování AWS EventStream, rámce událostí AMZN, odhad tokenů
|
||||
`index.ts` | — | Továrna: název poskytovatele map → třída exekutoru s výchozím záložním nastavením
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Obslužné rutiny ( `open-sse/handlers/` )
|
||||
|
||||
**Orchestrační vrstva** – koordinuje překlad, provádění, streamování a zpracování chyb.
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`chatCore.ts` | **Centrální orchestrátor** (~600 řádků). Zvládá kompletní životní cyklus požadavku: detekce formátu → překlad → odeslání exekutoru → streamovaná/nestreamovaná odpověď → aktualizace tokenu → zpracování chyb → protokolování využití.
|
||||
`responsesHandler.ts` | Adaptér pro OpenAI Responses API: převádí formát odpovědí → Dokončení chatu → odesílá do `chatCore` → převádí SSE zpět do formátu odpovědí.
|
||||
`embeddings.ts` | Obslužná rutina generování embeddingu: řeší model embeddingu → poskytovatele, odesílá do API poskytovatele, vrací odpověď na embedding kompatibilní s OpenAI. Podporuje 6+ poskytovatelů.
|
||||
`imageGeneration.ts` | Obslužná rutina generování obrázků: řeší model obrázku → poskytovatele, podporuje režimy kompatibilní s OpenAI, Gemini-image (Antigravity) a fallback (Nebius). Vrací obrázky v base64 nebo URL.
|
||||
|
||||
#### Životní cyklus požadavku (chatCore.ts)
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant Client
|
||||
participant chatCore
|
||||
participant Translator
|
||||
participant Executor
|
||||
participant Provider
|
||||
|
||||
Client->>chatCore: Request (any format)
|
||||
chatCore->>chatCore: Detect source format
|
||||
chatCore->>chatCore: Check bypass patterns
|
||||
chatCore->>chatCore: Resolve model & provider
|
||||
chatCore->>Translator: Translate request (source → OpenAI → target)
|
||||
chatCore->>Executor: Get executor for provider
|
||||
Executor->>Executor: Build URL, headers, transform request
|
||||
Executor->>Executor: Refresh credentials if needed
|
||||
Executor->>Provider: HTTP fetch (streaming or non-streaming)
|
||||
|
||||
alt Streaming
|
||||
Provider-->>chatCore: SSE stream
|
||||
chatCore->>chatCore: Pipe through SSE transform stream
|
||||
Note over chatCore: Transform stream translates<br/>each chunk: target → OpenAI → source
|
||||
chatCore-->>Client: Translated SSE stream
|
||||
else Non-streaming
|
||||
Provider-->>chatCore: JSON response
|
||||
chatCore->>Translator: Translate response
|
||||
chatCore-->>Client: Translated JSON
|
||||
end
|
||||
|
||||
alt Error (401, 429, 500...)
|
||||
chatCore->>Executor: Retry with credential refresh
|
||||
chatCore->>chatCore: Account fallback logic
|
||||
end
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.4 Služby ( `open-sse/services/` )
|
||||
|
||||
Obchodní logika, která podporuje obslužné rutiny a vykonavatele.
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`provider.ts` | **Detekce formátu** ( `detectFormat` ): analyzuje strukturu těla požadavku a identifikuje formáty Claude/OpenAI/Gemini/Antigravity/Responses (včetně heuristiky `max_tokens` pro Claude). Dále: tvorba URL, tvorba hlaviček, normalizace konfigurace thinking. Podporuje dynamické poskytovatele kompatibilní `openai-compatible-*` a `anthropic-compatible-*` .
|
||||
`model.ts` | Analýza řetězců modelu ( `claude/model-name` → `{provider: "claude", model: "model-name"}` ), rozlišení aliasů s detekcí kolizí, sanitizace vstupu (odmítá průchod cestou/řídicí znaky) a rozlišení informací o modelu s podporou asynchronních metod pro získávání aliasů.
|
||||
`accountFallback.ts` | Ovládání limitů rychlosti: exponenciální upomínka (1 s → 2 s → 4 s → max. 2 min), správa doby zpoždění účtu, klasifikace chyb (které chyby spouštějí fallback a které ne).
|
||||
`tokenRefresh.ts` | Aktualizace tokenu OAuth pro **všechny poskytovatele** : Google (Gemini, Antigravity), Claude, Codex, Qwen, iFlow, GitHub (duální token OAuth + Copilot), Kiro (AWS SSO OIDC + sociální ověřování). Zahrnuje mezipaměť deduplikace promise za provozu a opakování s exponenciálním zpožděním.
|
||||
`combo.ts` | **Kombinované modely** : řetězce záložních modelů. Pokud model A selže s chybou způsobilou pro záložní model, zkuste model B, poté C atd. Vrací skutečné stavové kódy upstreamu.
|
||||
`usage.ts` | Načítá data o kvótách/využití z API poskytovatelů (kvóty GitHub Copilot, kvóty modelu Antigravity, limity rychlosti Codexu, rozpisy využití Kiro, nastavení Claude).
|
||||
`accountSelector.ts` | Inteligentní výběr účtu s algoritmem bodování: pro výběr optimálního účtu pro každý požadavek se zohledňuje priorita, zdravotní stav, pozice v systému round robin a stav ochlazování.
|
||||
`contextManager.ts` | Správa životního cyklu kontextu požadavku: vytváří a sleduje objekty kontextu pro každý požadavek s metadaty (ID požadavku, časová razítka, informace o poskytovateli) pro ladění a protokolování.
|
||||
`ipFilter.ts` | Řízení přístupu založené na IP adrese: podporuje režimy povolených seznamů a blokovaných seznamů. Před zpracováním požadavků API ověřuje IP adresu klienta podle nakonfigurovaných pravidel.
|
||||
`sessionManager.ts` | Sledování relací s otisky prstů klientů: sleduje aktivní relace pomocí hašovaných identifikátorů klientů, monitoruje počty požadavků a poskytuje metriky relací.
|
||||
`signatureCache.ts` | Mezipaměť deduplikace na základě signatur požadavků: zabraňuje duplicitním požadavkům ukládáním nedávných signatur požadavků do mezipaměti a vrácením odpovědí z mezipaměti pro identické požadavky v rámci časového okna.
|
||||
`systemPrompt.ts` | Globální vložení systémového výzvy: přidá konfigurovatelnou systémovou výzvu ke všem požadavkům s možností kompatibility pro jednotlivé poskytovatele.
|
||||
`thinkingBudget.ts` | Správa rozpočtu tokenů uvažování: podporuje režimy průchodu, automatický (konfigurace strip thinking), vlastní (pevný rozpočet) a adaptivní (měřítko složitosti) pro řízení tokenů myšlení/uvažování.
|
||||
`wildcardRouter.ts` | Směrování podle vzorů zástupných znaků: rozpoznává vzory zástupných znaků (např. `*/claude-*` ) na konkrétní páry poskytovatel/model na základě dostupnosti a priority.
|
||||
|
||||
#### Deduplikace obnovení tokenů
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant R1 as Request 1
|
||||
participant R2 as Request 2
|
||||
participant Cache as refreshPromiseCache
|
||||
participant OAuth as OAuth Provider
|
||||
|
||||
R1->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: No in-flight promise
|
||||
Cache->>OAuth: Start refresh
|
||||
R2->>Cache: getAccessToken("gemini", token)
|
||||
Cache->>Cache: Found in-flight promise
|
||||
Cache-->>R2: Return existing promise
|
||||
OAuth-->>Cache: New access token
|
||||
Cache-->>R1: New access token
|
||||
Cache-->>R2: Same access token (shared)
|
||||
Cache->>Cache: Delete cache entry
|
||||
```
|
||||
|
||||
#### Záložní stavový automat účtu
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> Active
|
||||
Active --> Error: Request fails (401/429/500)
|
||||
Error --> Cooldown: Apply backoff
|
||||
Cooldown --> Active: Cooldown expires
|
||||
Active --> Active: Request succeeds (reset backoff)
|
||||
|
||||
state Error {
|
||||
[*] --> ClassifyError
|
||||
ClassifyError --> ShouldFallback: Rate limit / Auth / Transient
|
||||
ClassifyError --> NoFallback: 400 Bad Request
|
||||
}
|
||||
|
||||
state Cooldown {
|
||||
[*] --> ExponentialBackoff
|
||||
ExponentialBackoff: Level 0 = 1s
|
||||
ExponentialBackoff: Level 1 = 2s
|
||||
ExponentialBackoff: Level 2 = 4s
|
||||
ExponentialBackoff: Max = 2min
|
||||
}
|
||||
```
|
||||
|
||||
#### Řetězec kombinovaných modelů
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Request with\ncombo model"] --> B["Model A"]
|
||||
B -->|"2xx Success"| C["Return response"]
|
||||
B -->|"429/401/500"| D{"Fallback\neligible?"}
|
||||
D -->|Yes| E["Model B"]
|
||||
D -->|No| F["Return error"]
|
||||
E -->|"2xx Success"| C
|
||||
E -->|"429/401/500"| G{"Fallback\neligible?"}
|
||||
G -->|Yes| H["Model C"]
|
||||
G -->|No| F
|
||||
H -->|"2xx Success"| C
|
||||
H -->|"Fail"| I["All failed →\nReturn last status"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.5 Překladač ( `open-sse/translator/` )
|
||||
|
||||
**Modul pro překlad formátů** využívající systém samoregistrujících se pluginů.
|
||||
|
||||
#### Architektura
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
subgraph "Request Translation"
|
||||
A["Claude → OpenAI"]
|
||||
B["Gemini → OpenAI"]
|
||||
C["Antigravity → OpenAI"]
|
||||
D["OpenAI Responses → OpenAI"]
|
||||
E["OpenAI → Claude"]
|
||||
F["OpenAI → Gemini"]
|
||||
G["OpenAI → Kiro"]
|
||||
H["OpenAI → Cursor"]
|
||||
end
|
||||
|
||||
subgraph "Response Translation"
|
||||
I["Claude → OpenAI"]
|
||||
J["Gemini → OpenAI"]
|
||||
K["Kiro → OpenAI"]
|
||||
L["Cursor → OpenAI"]
|
||||
M["OpenAI → Claude"]
|
||||
N["OpenAI → Antigravity"]
|
||||
O["OpenAI → Responses"]
|
||||
end
|
||||
```
|
||||
|
||||
Adresář | Soubory | Popis
|
||||
--- | --- | ---
|
||||
`request/` | 8 překladatelů | Převod těl požadavků mezi formáty. Každý soubor se při importu sám zaregistruje pomocí `register(from, to, fn)` .
|
||||
`response/` | 7 překladatelů | Převádí bloky odpovědí streamovaných dat mezi formáty. Zpracovává typy událostí SSE, myšlenkové bloky a volání nástrojů.
|
||||
`helpers/` | 6 pomocníků | Sdílené utility: `claudeHelper` (extrakce systémových prompts, thinking config), `geminiHelper` (mapování částí/obsahu), `openaiHelper` (filtrování formátů), `toolCallHelper` (generování ID, vkládání chybějících odpovědí), `maxTokensHelper` , `responsesApiHelper` .
|
||||
`index.ts` | — | Překladový engine: `translateRequest()` , `translateResponse()` , správa stavu, registr.
|
||||
`formats.ts` | — | Formátovací konstanty: `OPENAI` , `CLAUDE` , `GEMINI` , `ANTIGRAVITY` , `KIRO` , `CURSOR` , `OPENAI_RESPONSES` .
|
||||
|
||||
#### Klíčový design: Samoregistrující se pluginy
|
||||
|
||||
```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 Nástroje ( `open-sse/utils/` )
|
||||
|
||||
Soubor | Účel
|
||||
--- | ---
|
||||
`error.ts` | Vytváření chybové odezvy (formát kompatibilní s OpenAI), parsování chyb v upstreamu, extrakce doby opakování Antigravity z chybových zpráv, streamování chyb SSE.
|
||||
`stream.ts` | **SSE Transform Stream** — základní streamovací kanál. Dva režimy: `TRANSLATE` (plný překlad formátu) a `PASSTHROUGH` (normalizace + extrakce využití). Zpracovává ukládání bloků do vyrovnávací paměti, odhad využití a sledování délky obsahu. Instance kodéru/dekodéru pro každý stream se vyhýbají sdílenému stavu.
|
||||
`streamHelpers.ts` | Nízkoúrovňové utility SSE: `parseSSELine` (tolerantní k bílým znakům), `hasValuableContent` (filtruje prázdné segmenty pro OpenAI/Claude/Gemini), `fixInvalidId` , `formatSSE` (serializace SSE s ohledem na formát s čištěním `perf_metrics` ).
|
||||
`usageTracking.ts` | Extrakce využití tokenů z libovolného formátu (Claude/OpenAI/Gemini/Responses), odhad s oddělenými poměry znaků na token pro jednotlivé nástroje/zprávy, přidání vyrovnávací paměti (bezpečnostní rezerva 2000 tokenů), filtrování polí specifických pro formát, protokolování konzole s barvami ANSI.
|
||||
`requestLogger.ts` | Protokolování požadavků na základě souborů (přihlášení pomocí `ENABLE_REQUEST_LOGS=true` ). Vytváří složky relací s očíslovanými soubory: `1_req_client.json` → `7_res_client.txt` . Veškeré I/O operace jsou asynchronní (aktivní a zapomenutý). Maskuje citlivé hlavičky.
|
||||
`bypassHandler.ts` | Zachycuje specifické vzory z Claude CLI (extrakce názvu, zahřívání, počet) a vrací falešné odpovědi bez volání jakéhokoli poskytovatele. Podporuje streamování i nestreamování. Záměrně omezeno na rozsah Claude CLI.
|
||||
`networkProxy.ts` | Rozpozná URL odchozí proxy pro daného poskytovatele s prioritou: konfigurace specifická pro poskytovatele → globální konfigurace → proměnné prostředí ( `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` ). Podporuje výjimky `NO_PROXY` . Ukládá konfiguraci do mezipaměti po dobu 30 sekund.
|
||||
|
||||
#### Streamovací kanál SSE
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Provider SSE stream"] --> B["TextDecoder\n(per-stream instance)"]
|
||||
B --> C["Buffer lines\n(split on newline)"]
|
||||
C --> D["parseSSELine()\n(trim whitespace, parse JSON)"]
|
||||
D --> E{"Mode?"}
|
||||
E -->|TRANSLATE| F["translateResponse()\ntarget → OpenAI → source"]
|
||||
E -->|PASSTHROUGH| G["fixInvalidId()\nnormalize chunk"]
|
||||
F --> H["hasValuableContent()\nfilter empty chunks"]
|
||||
G --> H
|
||||
H -->|"Has content"| I["extractUsage()\ntrack token counts"]
|
||||
H -->|"Empty"| J["Skip chunk"]
|
||||
I --> K["formatSSE()\nserialize + clean perf_metrics"]
|
||||
K --> L["TextEncoder\n(per-stream instance)"]
|
||||
L --> M["Enqueue to\nclient stream"]
|
||||
|
||||
style A fill:#f9f,stroke:#333
|
||||
style M fill:#9f9,stroke:#333
|
||||
```
|
||||
|
||||
#### Struktura relace protokolování požadavků
|
||||
|
||||
```
|
||||
logs/
|
||||
└── claude_gemini_claude-sonnet_20260208_143045/
|
||||
├── 1_req_client.json ← Raw client request
|
||||
├── 2_req_source.json ← After initial conversion
|
||||
├── 3_req_openai.json ← OpenAI intermediate format
|
||||
├── 4_req_target.json ← Final target format
|
||||
├── 5_res_provider.txt ← Provider SSE chunks (streaming)
|
||||
├── 5_res_provider.json ← Provider response (non-streaming)
|
||||
├── 6_res_openai.txt ← OpenAI intermediate chunks
|
||||
├── 7_res_client.txt ← Client-facing SSE chunks
|
||||
└── 6_error.json ← Error details (if any)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4.7 Aplikační vrstva ( `src/` )
|
||||
|
||||
Adresář | Účel
|
||||
--- | ---
|
||||
`src/app/` | Webové uživatelské rozhraní, trasy API, middleware Express, obslužné rutiny zpětných volání OAuth
|
||||
`src/lib/` | Přístup k databázi ( `localDb.ts` , `usageDb.ts` ), ověřování, sdílení
|
||||
`src/mitm/` | Nástroje proxy typu „man-in-the-middle“ pro zachycení provozu poskytovatelů
|
||||
`src/models/` | Definice modelů databáze
|
||||
`src/shared/` | Obálky kolem funkcí open-sse (provider, stream, error atd.)
|
||||
`src/sse/` | Obslužné rutiny koncových bodů SSE, které propojují knihovnu open-sse s trasami Express
|
||||
`src/store/` | Správa stavu aplikací
|
||||
|
||||
#### Významné trasy API
|
||||
|
||||
Trasa | Metody | Účel
|
||||
--- | --- | ---
|
||||
`/api/provider-models` | ZÍSKAT/ODESLAT/SMAZAT | CRUD pro vlastní modely na poskytovatele
|
||||
`/api/models/catalog` | ZÍSKAT | Agregovaný katalog všech modelů (chat, embedding, image, custom) seskupených podle poskytovatele
|
||||
`/api/settings/proxy` | ZÍSKAT/VLOŽIT/ODSTRANIT | Konfigurace hierarchické odchozí proxy ( `global/providers/combos/keys` )
|
||||
`/api/settings/proxy/test` | ZVEŘEJNIT | Ověřuje připojení proxy a vrací veřejnou IP adresu/latenci
|
||||
`/v1/providers/[provider]/chat/completions` | ZVEŘEJNIT | Vyhrazené dokončování chatu pro jednotlivé poskytovatele s ověřováním modelu
|
||||
`/v1/providers/[provider]/embeddings` | ZVEŘEJNIT | Vyhrazené vkládání pro jednotlivé poskytovatele s ověřováním modelu
|
||||
`/v1/providers/[provider]/images/generations` | ZVEŘEJNIT | Vyhrazené generování obrázků pro každého poskytovatele s ověřováním modelu
|
||||
`/api/settings/ip-filter` | ZÍSKAT/VLOŽIT | Správa povolených/blokovaných IP adres
|
||||
`/api/settings/thinking-budget` | ZÍSKAT/VLOŽIT | Konfigurace rozpočtu tokenů zdůvodnění (průchozí/automatická/vlastní/adaptivní)
|
||||
`/api/settings/system-prompt` | ZÍSKAT/VLOŽIT | Globální vložení systémového promptu pro všechny požadavky
|
||||
`/api/sessions` | ZÍSKAT | Sledování a metriky aktivních relací
|
||||
`/api/rate-limits` | ZÍSKAT | Stav limitu sazby na účet
|
||||
|
||||
---
|
||||
|
||||
## 5. Klíčové návrhové vzory
|
||||
|
||||
### 5.1 Překlad typu Hub-and-Spoke
|
||||
|
||||
Všechny formáty se překládají prostřednictvím **formátu OpenAI jako ústředny** . Přidání nového poskytovatele vyžaduje napsání pouze **jednoho páru** překladačů (do/z OpenAI), nikoli N párů.
|
||||
|
||||
### 5.2 Vzor strategie exekutora
|
||||
|
||||
Každý poskytovatel má vyhrazenou třídu exekutoru, která dědí z `BaseExecutor` . Továrna v `executors/index.ts` vybere ten správný za běhu.
|
||||
|
||||
### 5.3 Systém samoregistračních pluginů
|
||||
|
||||
Moduly překladače se při importu registrují pomocí `register()` . Přidání nového překladače znamená pouze vytvoření souboru a jeho import.
|
||||
|
||||
### 5.4 Záložní účet s exponenciálním oddlužením
|
||||
|
||||
Když poskytovatel vrátí 429/401/500, systém může přepnout na další účet s exponenciálním zpožděním (1s → 2s → 4s → max. 2min).
|
||||
|
||||
### 5.5 Kombinované modelové řetězy
|
||||
|
||||
„Kombinace“ seskupuje více řetězců `provider/model` . Pokud první selže, automaticky se vrátí k dalšímu.
|
||||
|
||||
### 5.6 Stavový streamovací překlad
|
||||
|
||||
Překlad odpovědí udržuje stav napříč bloky SSE (sledování myšlenkových bloků, akumulace volání nástrojů, indexování bloků obsahu) prostřednictvím mechanismu `initState()` .
|
||||
|
||||
### 5.7 Bezpečnostní vyrovnávací paměť pro použití
|
||||
|
||||
K hlášenému využití je přidána vyrovnávací paměť o kapacitě 2000 tokenů, aby se zabránilo tomu, že klienti dosáhnou limitů kontextového okna v důsledku režijních nákladů systémových výzev a překladu formátu.
|
||||
|
||||
---
|
||||
|
||||
## 6. Podporované formáty
|
||||
|
||||
Formát | Směr | Identifikátor
|
||||
--- | --- | ---
|
||||
Dokončení chatu OpenAI | zdroj + cíl | `openai`
|
||||
API pro odpovědi OpenAI | zdroj + cíl | `openai-responses`
|
||||
Antropický Claude | zdroj + cíl | `claude`
|
||||
Google Gemini | zdroj + cíl | `gemini`
|
||||
Rozhraní příkazového řádku Google Gemini | pouze cíl | `gemini-cli`
|
||||
Antigravitace | zdroj + cíl | `antigravity`
|
||||
AWS Kiro | pouze cíl | `kiro`
|
||||
Kurzor | pouze cíl | `cursor`
|
||||
|
||||
---
|
||||
|
||||
## 7. Podporovaní poskytovatelé
|
||||
|
||||
Poskytovatel | Metoda ověřování | Vykonavatel | 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á hlavičku `x-goog-api-key`
|
||||
Rozhraní příkazového řádku Google Gemini | OAuth | GeminiCLI | Používá koncový bod `streamGenerateContent`
|
||||
Antigravitace | OAuth | Antigravitace | Záložní více URL adres, vlastní analýza opakovaných pokusů
|
||||
OpenAI | Klíč API | Výchozí | Autorizace standardního nosiče
|
||||
Kodex | OAuth | Kodex | Vkládá systémové instrukce, řídí myšlení
|
||||
GitHub Copilot | OAuth + token Copilot | Github | Duální token, napodobování záhlaví VSCode
|
||||
Kiro (AWS) | AWS SSO OIDC nebo sociální sítě | Kiro | Analýza binárního EventStreamu
|
||||
IDE kurzoru | Autorizace kontrolního součtu | Kurzor | Kódování Protobuf, kontrolní součty SHA-256
|
||||
Qwen | OAuth | Výchozí | Standardní ověřování
|
||||
iFlow | OAuth (základní + nosič) | Výchozí | Duální hlavička pro autorizaci
|
||||
OpenRouter | Klíč API | Výchozí | Autorizace standardního nosiče
|
||||
GLM, Kimi, MiniMax | Klíč API | Výchozí | Kompatibilní s Claude, použijte `x-api-key`
|
||||
`openai-compatible-*` | Klíč API | Výchozí | Dynamické: jakýkoli koncový bod kompatibilní s OpenAI
|
||||
`anthropic-compatible-*` | Klíč API | Výchozí | Dynamický: jakýkoli koncový bod kompatibilní s Claude
|
||||
|
||||
---
|
||||
|
||||
## 8. Souhrn datového toku
|
||||
|
||||
### Žádost o streamování
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor\nbuildUrl + buildHeaders"]
|
||||
D --> E["fetch(providerURL)"]
|
||||
E --> F["createSSEStream()\nTRANSLATE mode"]
|
||||
F --> G["parseSSELine()"]
|
||||
G --> H["translateResponse()\ntarget → OpenAI → source"]
|
||||
H --> I["extractUsage()\n+ addBuffer"]
|
||||
I --> J["formatSSE()"]
|
||||
J --> K["Client receives\ntranslated SSE"]
|
||||
K --> L["logUsage()\nsaveRequestUsage()"]
|
||||
```
|
||||
|
||||
### Žádost o nestreamování
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Client"] --> B["detectFormat()"]
|
||||
B --> C["translateRequest()\nsource → OpenAI → target"]
|
||||
C --> D["Executor.execute()"]
|
||||
D --> E["translateResponse()\ntarget → OpenAI → source"]
|
||||
E --> F["Return JSON\nresponse"]
|
||||
```
|
||||
|
||||
### Obtokový tok (Claude CLI)
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A["Claude CLI request"] --> B{"Match bypass\npattern?"}
|
||||
B -->|"Title/Warmup/Count"| C["Generate fake\nOpenAI response"]
|
||||
B -->|"No match"| D["Normal flow"]
|
||||
C --> E["Translate to\nsource format"]
|
||||
E --> F["Return without\ncalling provider"]
|
||||
```
|
||||
273
docs/i18n/cs/CONTRIBUTING.md
Normal file
273
docs/i18n/cs/CONTRIBUTING.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# Přispívání k OmniRoute
|
||||
|
||||
Děkujeme za váš zájem o přispění! Tato příručka obsahuje vše, co potřebujete k zahájení.
|
||||
|
||||
---
|
||||
|
||||
## Nastavení vývoje
|
||||
|
||||
### Předpoklady
|
||||
|
||||
- **Node.js** 20+ (doporučeno: 22 LTS)
|
||||
- **npm** 10+
|
||||
- **Git**
|
||||
|
||||
### Klonovat a instalovat
|
||||
|
||||
```bash
|
||||
git clone https://github.com/diegosouzapw/OmniRoute.git
|
||||
cd OmniRoute
|
||||
npm install
|
||||
```
|
||||
|
||||
### Proměnné prostředí
|
||||
|
||||
```bash
|
||||
# Create your .env from the template
|
||||
cp .env.example .env
|
||||
|
||||
# Generate required secrets
|
||||
echo "JWT_SECRET=$(openssl rand -base64 48)" >> .env
|
||||
echo "API_KEY_SECRET=$(openssl rand -hex 32)" >> .env
|
||||
```
|
||||
|
||||
Klíčové proměnné pro vývoj:
|
||||
|
||||
Proměnná | Výchozí nastavení pro vývoj | Popis
|
||||
--- | --- | ---
|
||||
`PORT` | `3000` | Port serveru
|
||||
`NEXT_PUBLIC_BASE_URL` | `http://localhost:3000` | Základní URL pro frontend
|
||||
`JWT_SECRET` | (vygenerovat výše) | Tajemství podpisu JWT
|
||||
`INITIAL_PASSWORD` | `123456` | První přihlašovací heslo
|
||||
`ENABLE_REQUEST_LOGS` | `false` | Povolit protokoly požadavků na ladění
|
||||
|
||||
### Spuštěno lokálně
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
Výchozí adresy URL:
|
||||
|
||||
- **Dashboard** : `http://localhost:3000/dashboard`
|
||||
- **API** : `http://localhost:3000/v1`
|
||||
|
||||
---
|
||||
|
||||
## Pracovní postup Gitu
|
||||
|
||||
> ⚠️ **NIKDY se necommitujte přímo do `main` .** Vždy používejte větve feature.
|
||||
|
||||
```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
|
||||
```
|
||||
|
||||
### Pojmenování poboček
|
||||
|
||||
Předpona | Účel
|
||||
--- | ---
|
||||
`feat/` | Nové funkce
|
||||
`fix/` | Opravy chyb
|
||||
`refactor/` | Restrukturalizace kódu
|
||||
`docs/` | Změny dokumentace
|
||||
`test/` | Doplnění/opravy testů
|
||||
`chore/` | Nástroje, CI, závislosti
|
||||
|
||||
### Zprávy o potvrzení
|
||||
|
||||
Postupujte podle [konvenčních commitů](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
|
||||
```
|
||||
|
||||
Rozsahy: `db` , `sse` , `oauth` , `dashboard` , `api` , `cli` , `docker` , `ci` .
|
||||
|
||||
---
|
||||
|
||||
## Spouštění testů
|
||||
|
||||
```bash
|
||||
# All unit tests
|
||||
npm test
|
||||
npm run test:unit
|
||||
|
||||
# Specific test suites
|
||||
npm run test:security # Security tests
|
||||
npm run test:fixes # Fix verification tests
|
||||
|
||||
# With coverage
|
||||
npm run test:coverage
|
||||
|
||||
# E2E tests (requires Playwright)
|
||||
npm run test:e2e
|
||||
|
||||
# Lint + format check
|
||||
npm run lint
|
||||
npm run check
|
||||
```
|
||||
|
||||
Aktuální stav testování: **368+ jednotkových testů** zahrnujících:
|
||||
|
||||
- Poskytovatelé překladů a konverze formátů
|
||||
- Omezení rychlosti, jistič a odolnost
|
||||
- Sémantická mezipaměť, idempotence, sledování průběhu
|
||||
- Databázové operace a schéma
|
||||
- Toky a ověřování OAuth
|
||||
- Ověření koncového bodu API
|
||||
|
||||
---
|
||||
|
||||
## Styl kódu
|
||||
|
||||
- **ESLint** — Spustí `npm run lint` před commitem
|
||||
- **Hezčí** – Automaticky naformátováno pomocí `lint-staged` při commitu
|
||||
- **TypeScript** — Veškerý kód `src/` používá `.ts` / `.tsx` ; dokument s TSDoc ( `@param` , `@returns` , `@throws` )
|
||||
- **No `eval()`** — ESLint vynucuje `no-eval` , `no-implied-eval` , `no-new-func`
|
||||
- **Ověření Zod** — Použití schémat Zod pro ověřování vstupu API
|
||||
|
||||
---
|
||||
|
||||
## Struktura projektu
|
||||
|
||||
```
|
||||
src/ # TypeScript (.ts / .tsx)
|
||||
├── app/ # Next.js App Router
|
||||
│ ├── (dashboard)/ # Dashboard pages (.tsx)
|
||||
│ ├── api/ # API routes (.ts)
|
||||
│ └── login/ # Auth pages (.tsx)
|
||||
├── domain/ # Domain types and response helpers (.ts)
|
||||
├── lib/ # Core business logic (.ts)
|
||||
│ ├── db/ # SQLite database layer
|
||||
│ ├── oauth/ # OAuth services per provider
|
||||
│ ├── cacheLayer.ts # LRU cache
|
||||
│ ├── semanticCache.ts # Semantic response cache
|
||||
│ ├── idempotencyLayer.ts # Request deduplication
|
||||
│ └── localDb.ts # Settings facade (LowDB for config, SQLite for domain data)
|
||||
├── shared/
|
||||
│ ├── components/ # React components (.tsx)
|
||||
│ ├── middleware/ # Correlation IDs, etc.
|
||||
│ ├── utils/ # Circuit breaker, sanitizer, etc.
|
||||
│ └── validation/ # Zod schemas
|
||||
└── sse/ # SSE chat handlers (.ts)
|
||||
|
||||
open-sse/ # @omniroute/open-sse workspace (JavaScript)
|
||||
├── handlers/ # chatCore.js — main request handler
|
||||
├── services/ # Rate limit, fallback
|
||||
├── translators/ # Format converters (OpenAI ↔ Claude ↔ Gemini)
|
||||
└── utils/ # Progress tracker, stream helpers
|
||||
|
||||
tests/
|
||||
├── unit/ # Node.js test runner (.test.mjs)
|
||||
└── e2e/ # Playwright tests
|
||||
|
||||
docs/ # Documentation
|
||||
├── USER_GUIDE.md # Provider setup, CLI integration
|
||||
├── API_REFERENCE.md # All endpoints
|
||||
├── TROUBLESHOOTING.md # Common issues
|
||||
├── ARCHITECTURE.md # System architecture
|
||||
└── adr/ # Architecture Decision Records
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Přidání nového poskytovatele
|
||||
|
||||
### Krok 1: Služba OAuth (pokud používáte OAuth)
|
||||
|
||||
Vytvořte `src/lib/oauth/services/your-provider.ts` rozšiřující `OAuthService` :
|
||||
|
||||
```typescript
|
||||
import { OAuthService } from "../OAuthService";
|
||||
|
||||
export class YourProviderService extends OAuthService {
|
||||
constructor() {
|
||||
super({
|
||||
name: "your-provider",
|
||||
authUrl: "https://provider.com/oauth/authorize",
|
||||
tokenUrl: "https://provider.com/oauth/token",
|
||||
clientId: "...",
|
||||
scopes: ["..."],
|
||||
});
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Krok 2: Registrace poskytovatele
|
||||
|
||||
Přidat do `src/lib/oauth/providers.ts` :
|
||||
|
||||
```typescript
|
||||
import { YourProviderService } from "./services/your-provider";
|
||||
// Add to the providers map
|
||||
```
|
||||
|
||||
### Krok 3: Přidání konstant
|
||||
|
||||
Přidejte konstanty poskytovatele do `src/lib/providerConstants.ts` :
|
||||
|
||||
- Předpona poskytovatele (např. `yp/` )
|
||||
- Výchozí modely
|
||||
- Informace o cenách
|
||||
|
||||
### Krok 4: Přidání překladače (pokud se nejedná o formát OpenAI)
|
||||
|
||||
Pokud poskytovatel používá vlastní formát API, vytvořte překladač v `open-sse/translators/` .
|
||||
|
||||
### Krok 5: Přidání časového limitu
|
||||
|
||||
Přidejte konfiguraci časového limitu požadavku do `src/shared/utils/requestTimeout.ts` .
|
||||
|
||||
### Krok 6: Přidání testů
|
||||
|
||||
Pište jednotkové testy v `tests/unit/` které pokrývají minimálně:
|
||||
|
||||
- Registrace poskytovatele
|
||||
- Překlad žádostí/odpovědí
|
||||
- Ošetření chyb
|
||||
|
||||
---
|
||||
|
||||
## Kontrolní seznam žádostí o natažení
|
||||
|
||||
- [ ] Testy prošly ( `npm test` )
|
||||
- [ ] Průchody pro linting ( `npm run lint` )
|
||||
- [ ] Sestavení proběhlo úspěšně ( `npm run build` )
|
||||
- [ ] Pro nové veřejné funkce a rozhraní přidány typy TypeScript
|
||||
- [ ] Žádné pevně zakódované tajné kódy ani záložní hodnoty
|
||||
- [ ] Aktualizován CHANGELOG (pokud se změna týká uživatele)
|
||||
- [ ] Aktualizovaná dokumentace (pokud je to relevantní)
|
||||
|
||||
---
|
||||
|
||||
## Uvolnění
|
||||
|
||||
Když je vytvořena nová verze GitHubu (např. `v0.4.0` ), balíček je **automaticky publikován do npm** prostřednictvím akcí GitHubu:
|
||||
|
||||
```bash
|
||||
gh release create v0.4.0 --title "v0.4.0" --generate-notes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Získání pomoci
|
||||
|
||||
- **Architektura** : Viz [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md)
|
||||
- **Problémy** : [github.com/diegosouzapw/OmniRoute/issues](https://github.com/diegosouzapw/OmniRoute/issues)
|
||||
- **ADR** : Viz `docs/adr/`
|
||||
143
docs/i18n/cs/FEATURES.md
Normal file
143
docs/i18n/cs/FEATURES.md
Normal file
@@ -0,0 +1,143 @@
|
||||
# OmniRoute — Galerie funkcí řídicího panelu
|
||||
|
||||
🌐 **Jazyky:** 🇺🇸 [angličtina](FEATURES.md) | 🇧🇷 [Português (Brazílie)](i18n/pt-BR/FEATURES.md) | 🇪🇸 [Español](i18n/es/FEATURES.md) | 🇫🇷 [Français](i18n/fr/FEATURES.md) | 🇮🇹 [Italiano](i18n/it/FEATURES.md) | 🇷🇺 [Русский](i18n/ru/FEATURES.md) | 🇨🇳[中文 (简体)](i18n/zh-CN/FEATURES.md) | 🇩🇪 [Deutsch](i18n/de/FEATURES.md) | 🇮🇳 [हिन्दी](i18n/in/FEATURES.md) | 🇹🇭 [ไทย](i18n/th/FEATURES.md) | 🇺🇦 [Українська](i18n/uk-UA/FEATURES.md) | 🇸🇦 [العربية](i18n/ar/FEATURES.md) | 🇯🇵[日本語](i18n/ja/FEATURES.md)| 🇻🇳 [Tiếng Việt](i18n/vi/FEATURES.md) | 🇧🇬 [Български](i18n/bg/FEATURES.md) | 🇩🇰 [Dánsko](i18n/da/FEATURES.md) | 🇫🇮 [Suomi](i18n/fi/FEATURES.md) | 🇮🇱 [עברית](i18n/he/FEATURES.md) | 🇭🇺 [maďarština](i18n/hu/FEATURES.md) | 🇮🇩 [Bahasa Indonésie](i18n/id/FEATURES.md) | 🇰🇷 [한국어](i18n/ko/FEATURES.md) | 🇲🇾 [Bahasa Melayu](i18n/ms/FEATURES.md) | 🇳🇱 [Nizozemsko](i18n/nl/FEATURES.md) | 🇳🇴 [Norsk](i18n/no/FEATURES.md) | 🇵🇹 [Português (Portugalsko)](i18n/pt/FEATURES.md) | 🇷🇴 [Română](i18n/ro/FEATURES.md) | 🇵🇱 [Polski](i18n/pl/FEATURES.md) | 🇸🇰 [Slovenčina](i18n/sk/FEATURES.md) | 🇸🇪 [Svenska](i18n/sv/FEATURES.md) | 🇵🇭 [Filipínec](i18n/phi/FEATURES.md) | 🇨🇿 [Čeština](i18n/cs/FEATURES.md)
|
||||
|
||||
Vizuální průvodce všemi částmi ovládacího panelu OmniRoute.
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Poskytovatelé
|
||||
|
||||
Spravujte připojení poskytovatelů AI: poskytovatelé OAuth (Claude Code, Codex, Gemini CLI), poskytovatelé klíčů API (Groq, DeepSeek, OpenRouter) a bezplatní poskytovatelé (iFlow, Qwen, Kiro). Účty Kiro zahrnují sledování zůstatku kreditů – zbývající kredity, celkový limit a datum obnovení jsou viditelné v Dashboard → Usage.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🎨 Kombinace
|
||||
|
||||
Vytvářejte kombinace směrování modelů pomocí 6 strategií: prioritní, vážená, kruhová, náhodná, nejméně používaná a nákladově optimalizovaná. Každá kombinace řetězí více modelů s automatickým přepínáním mezi nimi a zahrnuje rychlé šablony a kontroly připravenosti.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 📊 Analytika
|
||||
|
||||
Komplexní analýzy využití se spotřebou tokenů, odhady nákladů, mapami aktivit, týdenními distribučními grafy a rozpisy podle jednotlivých poskytovatelů.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🏥 Stav systému
|
||||
|
||||
Monitorování v reálném čase: dostupnost, paměť, verze, percentily latence (p50/p95/p99), statistiky mezipaměti a stavy jističů poskytovatelů.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 Překladatelské hřiště
|
||||
|
||||
Čtyři režimy pro ladění překladů API: **Playground** (převodník formátů), **Chat Tester** (živé požadavky), **Test Bench** (dávkové testy) a **Live Monitor** (stream v reálném čase).
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🎮 Modelové hřiště *(v2.0.9+)*
|
||||
|
||||
Otestujte libovolný model přímo z řídicího panelu. Vyberte poskytovatele, model a koncový bod, pište výzvy pomocí editoru Monaco, streamujte odpovědi v reálném čase, přerušte stream a zobrazte metriky časování.
|
||||
|
||||
---
|
||||
|
||||
## 🎨 Témata *(v2.0.5+)*
|
||||
|
||||
Přizpůsobitelná barevná témata pro celý dashboard. Vyberte si ze 7 přednastavených barev (korálová, modrá, červená, zelená, fialová, oranžová, azurová) nebo si vytvořte vlastní téma výběrem libovolné hexadecimální barvy. Podporuje světlý, tmavý a systémový režim.
|
||||
|
||||
---
|
||||
|
||||
## ⚙️ Nastavení
|
||||
|
||||
Komplexní panel nastavení s kartami:
|
||||
|
||||
- **Obecné** – Systémové úložiště, správa záloh (export/import databáze)
|
||||
- **Vzhled** – Výběr motivu (tmavý/světlý/systémový), přednastavené barevné motivy a vlastní barvy, viditelnost protokolu stavu
|
||||
- **Zabezpečení** — ochrana koncových bodů API, blokování vlastních poskytovatelů, filtrování IP adres, informace o relaci
|
||||
- **Směrování** — Aliasy modelů, degradace úloh na pozadí
|
||||
- **Odolnost** — Perzistence omezení rychlosti, ladění jističe
|
||||
- **Pokročilé** – Přepsání konfigurace
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔧 Nástroje CLI
|
||||
|
||||
Konfigurace nástrojů pro kódování s umělou inteligencí jedním kliknutím: Claude Code, Codex CLI, Gemini CLI, OpenClaw, Kilo Code, Antigravity, Cline, Continue, Cursor a Factory Droid. Nabízí automatické použití/resetování konfigurace, profily připojení a mapování modelů.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🤖 Agenti CLI *(v2.0.11+)*
|
||||
|
||||
Ovládací panel pro vyhledává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:
|
||||
|
||||
- **Stav instalace** — Nainstalováno / Nenalezeno s detekcí verze
|
||||
- **Odznaky protokolů** – stdio, HTTP atd.
|
||||
- **Vlastní agenti** — Registrace libovolného nástroje CLI pomocí formuláře (název, binární soubor, verze příkazu, argumenty spawn)
|
||||
- **Porovnávání otisků prstů v příkazovém řádku** – Přepínání pro jednotlivé poskytovatele pro porovnávání nativních podpisů požadavků v příkazovém řádku, čímž se snižuje riziko zablokování a zároveň se zachovává IP adresa proxy.
|
||||
|
||||
---
|
||||
|
||||
## 🖼️ Média *(v2.0.3+)*
|
||||
|
||||
Generujte obrázky, videa a hudbu z řídicího panelu. Podporuje OpenAI, xAI, Together, Hyperbolic, SD WebUI, ComfyUI, AnimateDiff, Stable Audio Open a MusicGen.
|
||||
|
||||
---
|
||||
|
||||
## 📝 Vyžádat si protokoly
|
||||
|
||||
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í tokenů, latenci a podrobnosti o odpovědi.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🌐 Koncový bod API
|
||||
|
||||
Váš jednotný koncový bod API s rozpisem funkcí: Dokončování 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 API. Podpora cloudového proxy pro vzdálený přístup.
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
## 🔑 Správa klíčů API
|
||||
|
||||
Vytvářejte, upravujte rozsah a rušte klíče API. Každý klíč lze omezit 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í.
|
||||
|
||||
---
|
||||
|
||||
## 📋 Záznam auditu
|
||||
|
||||
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 bezpečnostních událostí.
|
||||
|
||||
---
|
||||
|
||||
## 🖥️ Desktopová aplikace
|
||||
|
||||
Desktopová aplikace Native Electron pro Windows, macOS a Linux. Spouštějte OmniRoute jako samostatnou aplikaci s integrací do systémové lišty, podporou offline, automatickými aktualizacemi a instalací jedním kliknutím.
|
||||
|
||||
Klíčové vlastnosti:
|
||||
|
||||
- Dotazování připravenosti serveru (žádná prázdná obrazovka při studeném startu)
|
||||
- Systémový panel se správou portů
|
||||
- Zásady zabezpečení obsahu
|
||||
- Jednoinstanční zámek
|
||||
- Automatická aktualizace při restartu
|
||||
- Podmíněné uživatelské rozhraní pro platformu (semafory pro macOS, výchozí záhlaví okna pro Windows/Linux)
|
||||
- Zpevněné balení buildů Electron — symbolicky odkazované `node_modules` v samostatném balíčku jsou detekovány a odmítnuty před balením, čímž se zabrání závislosti na buildovacím stroji za běhu (v2.5.5+)
|
||||
|
||||
📖 Úplnou dokumentaci naleznete v [`electron/README.md`](../electron/README.md) .
|
||||
83
docs/i18n/cs/MCP-SERVER.md
Normal file
83
docs/i18n/cs/MCP-SERVER.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Dokumentace k serveru OmniRoute MCP
|
||||
|
||||
> Server protokolu kontextu modelu s 16 inteligentními nástroji
|
||||
|
||||
## Instalace
|
||||
|
||||
OmniRoute MCP je integrovaný. Spusťte ho pomocí:
|
||||
|
||||
```bash
|
||||
omniroute --mcp
|
||||
```
|
||||
|
||||
Nebo prostřednictvím open-sse transportu:
|
||||
|
||||
```bash
|
||||
# HTTP streamable transport (port 20130)
|
||||
omniroute --dev # MCP auto-starts on /mcp endpoint
|
||||
```
|
||||
|
||||
## Konfigurace IDE
|
||||
|
||||
Viz [konfigurace IDE](integrations/ide-configs.md) pro nastavení Antigravity, Cursoru, Copilota a Claude Desktopu.
|
||||
|
||||
---
|
||||
|
||||
## Základní nástroje (8)
|
||||
|
||||
Nástroj | Popis
|
||||
:-- | :--
|
||||
`omniroute_get_health` | Stav brány, jističe, provozuschopnost
|
||||
`omniroute_list_combos` | Všechny nakonfigurované kombinace s modely
|
||||
`omniroute_get_combo_metrics` | Metriky výkonu pro konkrétní kombinaci
|
||||
`omniroute_switch_combo` | Přepnout aktivní kombinaci podle ID/jména
|
||||
`omniroute_check_quota` | Stav kvóty pro jednotlivé poskytovatele nebo všechny
|
||||
`omniroute_route_request` | Odeslání dokončení chatu přes OmniRoute
|
||||
`omniroute_cost_report` | Analýza nákladů za určité časové období
|
||||
`omniroute_list_models_catalog` | Kompletní katalog modelů s funkcemi
|
||||
|
||||
## Pokročilé nástroje (8)
|
||||
|
||||
Nástroj | Popis
|
||||
:-- | :--
|
||||
`omniroute_simulate_route` | Simulace trasování na dryru s fallback stromem
|
||||
`omniroute_set_budget_guard` | Rozpočet relace s akcemi degradace/blokování/upozornění
|
||||
`omniroute_set_resilience_profile` | Použít konzervativní/vyvážený/agresivní předvolbu
|
||||
`omniroute_test_combo` | Živé testování všech modelů v kombinaci
|
||||
`omniroute_get_provider_metrics` | Podrobné metriky pro jednoho poskytovatele
|
||||
`omniroute_best_combo_for_task` | Doporučení pro splnění úkolu a jeho vhodnosti s alternativami
|
||||
`omniroute_explain_route` | Vysvětlete minulé rozhodnutí o trase
|
||||
`omniroute_get_session_snapshot` | Stav celé relace: náklady, tokeny, chyby
|
||||
|
||||
## Ověřování
|
||||
|
||||
Nástroje MCP jsou ověřovány pomocí rozsahů klíčů API. Každý nástroj vyžaduje specifické rozsahy:
|
||||
|
||||
Rozsah | Nástroje
|
||||
:-- | :--
|
||||
`read:health` | get_health, get_provider_metrics
|
||||
`read:combos` | seznam_kombinací, získání_kombinovaných_metrik
|
||||
`write:combos` | přepínač_kombinace
|
||||
`read:quota` | check_quote
|
||||
`write:route` | požadavek_trasy, simulace_trasy, testovací_kombinace
|
||||
`read:usage` | zpráva_o_nákladech, získání_snímku_relace, vysvětlení_trasy
|
||||
`write:config` | set_budget_guard, set_resilience_profile
|
||||
`read:models` | seznam_modelů_katalog, nejlepší_kombinace_pro_úkol
|
||||
|
||||
## Protokolování auditu
|
||||
|
||||
Každé volání nástroje je zaznamenáno do `mcp_tool_audit` s touto funkcí:
|
||||
|
||||
- Název nástroje, argumenty, výsledek
|
||||
- Trvání (ms), úspěch/neúspěch
|
||||
- Haš klíče API, časové razítko
|
||||
|
||||
## Soubory
|
||||
|
||||
Soubor | Účel
|
||||
:-- | :--
|
||||
`open-sse/mcp-server/server.ts` | Vytvoření MCP serveru + 16 registrací nástrojů
|
||||
`open-sse/mcp-server/transport.ts` | Stdio + HTTP transport
|
||||
`open-sse/mcp-server/auth.ts` | Ověření klíče API + rozsahu
|
||||
`open-sse/mcp-server/audit.ts` | Protokolování auditu volání nástrojů
|
||||
`open-sse/mcp-server/tools/advancedTools.ts` | 8 pokročilých manipulátorů s nástroji
|
||||
2010
docs/i18n/cs/README.md
Normal file
2010
docs/i18n/cs/README.md
Normal file
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user