🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇧🇦 bs · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
Versiya: v3.8.44 Oxirgi yangilanish: 2026-09-09 Auditoriya: Oʻrnatilgan xizmatlarni (9Router, CLIProxyAPI, Mux, Bifrost, open-wa) qoʻshuvchi, ularga xizmat koʻrsatuvchi yoki ularni nosozliklardan xalos qiluvchi muhandislar.
Oʻrnatilgan xizmatlar — OmniRoute oʻrnatadigan, nazorat qiladigan va toʻlaqonli marshrutlash maqsadlari sifatida taqdim etadigan, mahalliy oʻrnatilgan yordamchi jarayon vositalaridir. Tashqi provayderlardan (ularga internet orqali API kalitlari yordamida ulaniladi) farqli oʻlaroq, oʻrnatilgan xizmatlar OmniRoute bilan bir xil kompyuterda ishlaydi va loopback orqali aloqa qiladi.
- Umumiy koʻrinish
- Arxitektura — 4 qatlam
- Hayotiy sikl holatlari mashinasi
- API maʼlumotnomasi
- Xavfsizlik
- Yangi oʻrnatilgan xizmatni qoʻshish
- Nosozliklarni bartaraf etish
- Koʻp soʻraladigan savollar
Oltita xizmat ichki tarzda biriktirilgan:
| Xizmat | npm paketi | Standart port | Maqsad |
|---|---|---|---|
| 9Router | 9router |
20130 | OmniRoute quyi provayder sifatida foydalanishi mumkin bo‘lgan AI routeri. Modellar 9router/{sub}/{model} ko‘rinishida taqdim etiladi |
| CLIProxyAPI | GitHub reliz binar fayli (cliproxy) |
8317 | Anthropic CLI autentifikatsiya oqimlari uchun lokal proksi adapteri. OAuth tokenlarining muddati tugaganda zaxira marshrutlashni ta’minlaydi |
| Mux | mux (interfeyssiz mux server) |
8322 | Lokal agentlarni muvofiqlashtirish demoni (coder/mux). Faqat hayot sikli boshqariladi — marshrutlash maqsadi emas (LLM proksilash mavjud emas). |
| Bifrost | @maximhq/bifrost |
8080 | Go AI-shlyuzining retranslyatsiya bekendi. Ishlayotganida retranslyatsiya marshruti (/v1/relay/) tomonidan avtomatik tanlanadi |
| Dario | @askalf/dario |
3456 | Claude obunasi proksisi — Claude-Code formatidagi trafik uchun CLIProxyAPI muqobili/zaxirasi; kiritilgan kalit uning /admin/* OAuth boshqaruv qatlamini himoyalovchi DARIO_ADMIN_TOKEN qiymatiga aylanadi |
| open-wa | @open-wa/wa-automate |
8323 | WhatsApp Web avtomatlashtirishi (Puppeteer orqali interfeyssiz Chromium). Faqat hayot sikli boshqariladi — marshrutlash maqsadi emas. |
Oltala xizmat ham bir xil nazorat modeliga amal qiladi:
- OmniRoute ularni
DATA_DIR/services/{name}/ostiga o‘rnatadi (OmniRoute’ning o‘zpackage.jsonfaylidan ajratilgan holda) - OmniRoute ularni quyi jarayonlar sifatida ishga tushiradi va kuzatadi
- OmniRoute vaqtinchalik API kalitini quyi jarayon muhitiga kiritadi va uni uzilishlarsiz almashtiradi (tegishli hollarda)
- Barcha boshqaruv marshrutlari (
/api/services/*) LOCAL_ONLY — ularga faqat loopback orqali kirish mumkin (qat’iy qoida #17)
| Qaror | Qiymat |
|---|---|
| 9Router mahalliy UI’iga boshqaruv panelidan kirish | /dashboard/providers/services/9router/embed/* manzilidagi teskari proksi |
| O‘rnatish mexanizmi | execFile orqali npm install {package} (shell interpolyatsiyasisiz) |
| Foydalanish rejimi | Marshrutlash mexanizmida 9router/{sub}/{model} sifatida ro‘yxatdan o‘tgan provayder |
| API kalitini boshqarish | OmniRoute yaratadi, saqlashda shifrlaydi (AES-256-GCM) va env orqali kiritadi |
| Boshqaruv panelidagi joylashuv | /dashboard/providers/services (uchta ichki sahifa) |
| Avtomatik ishga tushirish | Har bir xizmat uchun alohida almashtirgich, standart holatda O‘CHIRILGAN |
┌────────────────────────────────────────────────────────────────────┐
│ 1-qatlam — UI │
│ /dashboard/providers/services (varaqlar: CLIProxyAPI | 9Router | Mux)│
│ Jonli loglar (SSE), Ishga tushirish/Toʻxtatish/Qayta ishga tushirish/Yangilash, Sozlamalar, Oʻrnatish│
│ │
│ src/app/(dashboard)/dashboard/providers/services/ │
│ ├── page.tsx Qobiq + ?tab= orqali varaqlarni yoʻnaltirish│
│ ├── tabs/ CliproxyServiceTab, NinerouterServiceTab,│
│ │ MuxServiceTab │
│ └── components/ ServiceStatusCard, ServiceLifecycleButtons,│
│ ServiceLogsPanel, ApiKeyCard, ... │
└──────────────────────┬─────────────────────────────────────────────┘
│ HTTP (Next.js fetch)
┌──────────────────────▼─────────────────────────────────────────────┐
│ 2-qatlam — API (LOCAL_ONLY — faqat loopback) │
│ │
│ /api/services/9router/{install|start|stop|restart|update| │
│ rotate-key|status|auto-start|logs} │
│ /api/services/cliproxy/{install|start|stop|restart|update| │
│ status|auto-start|logs} │
│ /api/services/mux/{install|start|stop|restart|update| │
│ status|auto-start|logs} │
│ /dashboard/providers/services/9router/embed/[...path] │
│ (teskari HTTP + WebSocket proksi → 9Router upstream) │
│ │
│ Cheklov: LOCAL_ONLY_API_PREFIXES tarkibiga "/api/services/" va │
│ "/dashboard/providers/services/*/embed/" kiradi │
└──────────────────────┬─────────────────────────────────────────────┘
│ jarayon ichidagi chaqiruvlar
┌──────────────────────▼─────────────────────────────────────────────┐
│ 3-qatlam — ServiceSupervisor (src/lib/services/) │
│ │
│ ServiceSupervisor.ts Umumiy supervayzer (child_process.spawn) │
│ ├── oʻrnatish: execFile('npm', ['install', pkg, '--prefix']) │
│ ├── ishga tushirish: spawn(node, [entrypoint], {env, cwd}) │
│ ├── api_key: crypto.randomBytes(32) → env NINEROUTER_API_KEY │
│ ├── port: 9Router uchun 20130 (sozlanishi mumkin) │
│ ├── loglar: stdio halqali buferi 5 MB → SSE hodisalari │
│ ├── holat: har 2–5 soniyada HTTP GET /health, sust tiklanish│
│ └── hayot sikli: SIGTERM 15 soniya → SIGKILL │
│ │
│ registry.ts getSupervisor(name) / registerSupervisor() │
│ bootstrap.ts Jarayon boshlanishida barcha SERVICES[] ni yuklaydi│
│ apiKey.ts getOrCreateApiKey(), generateServiceApiKey() │
│ modelSync.ts Davriy GET /v1/models → service_models jadvali │
│ ringBuffer.ts Aylanma log buferi (har bir xizmat uchun 5 MB) │
│ healthCheck.ts Soʻrov asosidagi HTTP holat tekshiruvi │
│ installers/ ninerouter.ts, cliproxy.ts, mux.ts, openwa.ts │
│ (oʻrnatuvchi adapterlar) │
└──────────────────────┬─────────────────────────────────────────────┘
│ OpenAI bilan mos HTTP (loopback)
┌──────────────────────▼─────────────────────────────────────────────┐
│ 4-qatlam — Provayder / Yoʻnaltirish │
│ │
│ open-sse/executors/ninerouter.ts │
│ Har bir soʻrovda port va API kalitini qayta izlaydi (keshlanmaydi).│
│ Proksilashdan oldin model id qiymatidan "9router/" prefiksini olib tashlaydi.│
│ Agar supervayzer "running" holatida boʻlmasa, 503 service_not_running qaytaradi.│
│ │
│ src/shared/constants/providers.ts │
│ "9router" uchun yozuv: isEmbeddedService: true │
│ │
│ open-sse/config/providerRegistry.ts │
│ Modellar "9router/{sub}/{model}" shaklida saqlanadi (prefiksli).│
│ Har 5 daqiqada modelSync.ts tomonidan sinxronlanadi. │
│ │
│ Mux FAQAT hayot sikli boʻyicha boshqariladi (1–3-qatlamlar) — u │
│ LLM proksisi emas, balki agentlarni orkestratsiya qilish demoni, │
│ shu sababli unda 4-qatlam ijrochisi/provayder yozuvi yoʻq va u │
│ hech qachon yoʻnaltirish nishoni boʻlmaydi. │
└────────────────────────────────────────────────────────────────────┘
| Fayl | Vazifasi |
|---|---|
src/lib/services/ServiceSupervisor.ts |
Asosiy klass: hayot sikli, qulf, holat, halqali bufer |
src/lib/services/bootstrap.ts |
Jarayon darajasida roʻyxatdan oʻtkazish va avtomatik ishga tushirish |
src/lib/services/registry.ts |
Singleton xarita tool → supervisor |
src/lib/services/apiKey.ts |
Kalit yaratish, saqlashda AES-256-GCM shifrlash |
src/lib/services/modelSync.ts |
Davriy model sinxronizatsiyasi (5 daqiqa) + talab boʻyicha |
src/lib/services/ringBuffer.ts |
SSE obunasi bilan 5 MB hajmli halqali jurnal buferi |
src/lib/services/healthCheck.ts |
HTTP holat tekshiruvi (sozlanadigan interval) |
src/lib/services/installers/ninerouter.ts |
9Router uchun npm orqali oʻrnatish/yangilash/oʻchirish |
src/lib/services/installers/cliproxy.ts |
CLIProxyAPI uchun npm orqali oʻrnatish/yangilash/oʻchirish |
src/lib/services/installers/mux.ts |
Mux uchun npm orqali oʻrnatish/yangilash/oʻchirish |
src/lib/services/installers/openwa.ts |
open-wa uchun npm orqali oʻrnatish/yangilash/oʻchirish |
src/app/api/services/9router/_lib.ts |
getOrInitSupervisor() yordamchi funksiyasi |
src/app/api/services/[name]/logs/route.ts |
Umumiy SSE jurnallari endpointi |
open-sse/executors/ninerouter.ts |
Provayder ijrochisi (4-qatlam) |
install()
┌─────────────┐ ──────────► ┌─────────────┐
│ not_installed│ │ stopped │◄──────────────────┐
└─────────────┘ └──────┬──────┘ │
│ start() │
▼ │ stop()
┌──────────┐ │
│ starting │ │
└────┬─────┘ │
holat tekshiruvi yaxshi│ nosozlik / SIGTERM │
┌────▼─────┐ (5 s ichida chiqish)│
│ running │──── nosozlik ───────►┤
└────┬─────┘ ┌─▼────┐
stop() │ │error │
▼ └──────┘
┌──────────┐
│ stopping │
└──────────┘
Holatlar version_manager DB jadvalida (status ustuni) saqlanadi va
ServiceSupervisor xotiradagi holatida aks ettiriladi. Ishlayotgan jarayon uchun
xotiradagi holat asosiy hisoblanadi; DB holati yuklanish paytidagi doimiy zaxira
hisoblanadi.
| Qayerdan | Hodisa | Qayerga |
|---|---|---|
not_installed |
install() muvaffaqiyatli |
stopped |
stopped |
start() chaqirildi |
starting |
starting |
holat tekshiruvi 200 qaytardi | running |
starting |
jarayon sog‘lom holatga kelmay chiqdi | error |
running |
stop() chaqirildi |
stopping → stopped |
running |
jarayon kutilmaganda chiqdi (< 5 s) | error (tezkor nosozlik) |
running |
jarayon kutilmaganda chiqdi (> 5 s) | error |
error |
start() chaqirildi |
starting |
| istalgan | stopping paytida stop() |
hech qanday amal yo‘q |
ServiceSupervisor hayot sikli amaliyotlarini asinxron amaliyot qulfi
(withLock()) orqali ketma-ketlashtiradi. Bir xil nazoratchida parallel start()
chaqiruvlari aniq bitta jarayonni ishga tushiradi; ikkinchi chaqiruvchi kutadi va
mavjud holatni qaytaradi. Bu, masalan, avtomatik ishga tushirish va UI tugmasi bir
vaqtda faollashganda poyga holatlarining oldini oladi.
/api/services/ ostidagi barcha marshrutlar LOCAL_ONLY hisoblanadi (faqat loopback, qatʼiy qoida #17).
Loopback bo‘lmagan so‘rovlar autentifikatsiya tokenidan qatʼi nazar 403 LOCAL_ONLY javobini oladi.
9Router’ni npm orqali o‘rnatadi. O‘zining package.json va node_modules/ fayllariga ega
DATA_DIR/services/9router/ katalogini yaratadi. OmniRoute’ning o‘z bog‘liqliklari bilan ziddiyatga kirishmaydi.
So‘rov tanasi (barchasi ixtiyoriy):
{ "version": "latest" }| Maydon | Tur | Standart qiymat | Tavsif |
|---|---|---|---|
version |
string |
"latest" |
O‘rnatiladigan npm versiya tegi yoki semver |
Javoblar:
| Holat | Tavsif |
|---|---|
200 |
{ ok: true, installedVersion: "x.y.z", path: "..." } |
400 |
So‘rov tanasi noto‘g‘ri (Zod validatsiyasi muvaffaqiyatsiz) |
409 |
O‘rnatish allaqachon bajarilmoqda (qulf band) |
500 |
npm o‘rnatilishi muvaffaqiyatsiz — tushunarli xato uchun messageni ko‘ring |
Izohlar: execFile('npm', [...])dan foydalanadi — shell va interpolatsiya yo‘q (qatʼiy qoida #13).
EACCES xatolari tushunarli xabarlar sifatida ko‘rsatiladi.
9Router’ni ishga tushiradi. Agar supervisor hali ro‘yxatdan o‘tkazilmagan bo‘lsa, uni ro‘yxatdan o‘tkazadi va
keyin supervisor.start()ni chaqiradi. Allaqachon ishlayotgan bo‘lsa, idempotent hisoblanadi.
So‘rov tanasi: yo‘q
Javoblar:
| Holat | Tavsif |
|---|---|
200 |
ServiceStatus obyekti (quyidagi sxemaga qarang) |
409 |
9Router o‘rnatilmagan (status: "not_installed") |
503 |
Ishga tushirish muvaffaqiyatsiz (jarayon xatosi — lastErrorga qarang) |
ServiceStatus sxemasi:
{
"tool": "9router",
"state": "running",
"pid": 12345,
"port": 20130,
"health": "healthy",
"startedAt": "2026-05-25T10:00:00.000Z",
"lastError": null
}9Router’ni xavfsiz tarzda to‘xtatadi. SIGTERM yuboradi, 15 soniya kutadi, so‘ng jarayon hali ham ishlayotgan bo‘lsa, SIGKILL yuboradi. Allaqachon to‘xtatilgan bo‘lsa, idempotent hisoblanadi.
So‘rov tanasi: yo‘q
Javoblar:
| Holat | Tavsif |
|---|---|
200 |
ServiceStatus (state: "stopped") |
503 |
To‘xtatish kutilmaganda muvaffaqiyatsiz bo‘ldi |
Amaliyot qulfi ostida stop() va undan keyin start() bajarilishiga teng.
So‘rov tanasi: yo‘q
Javoblar: start bilan bir xil (yakuniy ServiceStatusni qaytaradi).
9Router’ni yangiroq npm versiyasiga yangilaydi. Agar xizmat ishlayotgan bo‘lsa, avval u to‘xtatiladi, npm install ishga tushiriladi (yangiroq versiya mavjud joyga o‘rnatiladi), keyin esa xizmat qayta ishga tushiriladi.
So‘rov tanasi (barchasi ixtiyoriy):
{ "version": "latest" }Javoblar:
| Holat | Tavsif |
|---|---|
200 |
{ ok: true, previousVersion: "...", installedVersion: "..." } |
400 |
So‘rov tanasi noto‘g‘ri |
500 |
npm yangilanishi muvaffaqiyatsiz |
9Router uchun yangi API kalitini yaratadi, uni saqlashda shifrlaydi va xizmat yangi kalitni o‘z muhitidan olishi uchun uni qayta ishga tushiradi (agar ishlayotgan bo‘lsa). Eski kalit darhol bekor qilinadi.
So‘rov tanasi: yo‘q
Javoblar:
| Holat | Tavsif |
|---|---|
200 |
{ keyRotated: true, restarted: boolean } |
500 |
Kalitni almashtirish muvaffaqiyatsiz |
Xavfsizlik: Yangi kalit hech qachon javobda qaytarilmaydi (hisob maʼlumotlari sizib chiqmaydi).
U version_manager jadvalida shifrlangan holda (AES-256-GCM) saqlanadi.
Versiya metamaʼlumotlari va API kaliti ko‘rinishini o‘z ichiga olgan birlashtirilgan jonli + DB holatini qaytaradi.
Javoblar:
| Holat | Tavsif |
|---|---|
200 |
Quyidagi sxemaga qarang |
500 |
Holatni o‘qish muvaffaqiyatsiz bo‘ldi |
Javob sxemasi:
{
"tool": "9router",
"state": "running",
"pid": 12345,
"port": 20130,
"health": "healthy",
"startedAt": "2026-05-25T10:00:00.000Z",
"lastError": null,
"installedVersion": "1.2.3",
"latestVersion": "1.2.4",
"updateAvailable": true,
"apiKeyMasked": "nr_****abcd",
"autoStart": false,
"providerExpose": false
}Avtomatik ishga tushirish bayrog‘ini almashtiradi. enabled: true bo‘lsa, OmniRoute keyingi safar
ishga tushganda xizmat avtomatik ravishda ishga tushadi (agar xizmat o‘rnatilgan bo‘lsa).
So‘rov tanasi:
{ "enabled": true }Javoblar:
| Holat | Tavsif |
|---|---|
200 |
{ autoStart: true } |
400 |
So‘rov tanasi noto‘g‘ri |
9Router’ning stdout/stderr halqali buferidagi jonli loglarning SSE oqimi.
So‘rov parametrlari:
| Parametr | Tur | Standart qiymat | Tavsif |
|---|---|---|---|
tail |
integer |
200 | Dastlab yuboriladigan tarixiy satrlar soni (maksimal 1000) |
filter |
string |
yo‘q | Registrga bog‘liq bo‘lmagan quyi satr filtri (regex yo‘q — ReDoS’dan himoyalangan) |
SSE hodisalari:
| Hodisa | Maʼlumot | Tavsif |
|---|---|---|
snapshot |
LogLine[] |
Dastlabki tarixiy yakuniy qism |
log |
LogLine |
Jonli log satri |
heartbeat |
{} |
Har 15 soniyada ulanishni faol saqlash |
LogLine sxemasi:
{
"ts": 1716633600000,
"stream": "stdout",
"line": "[9router] Listening on :20130"
}Javoblar:
| Holat | Tavsif |
|---|---|
200 |
text/event-stream |
400 |
filter parametri juda uzun (> 200 ta belgi) |
404 |
Xizmat topilmadi (supervizor roʻyxatdan oʻtkazilmagan) |
CLIProxyAPI 9Router bilan bir xil endpoint tuzilishiga ega, ammo rotate-key mavjud emas,
buning oʻrniga accounts, provider-expose va auto-restart-adopted mavjud. Endi u
ishga tushirilganda kiritiladigan alohida maʼlumotlar tekisligi API kalitini oladi
(bootstrap.ts faylida needsApiKey: true, modelni sinxronlash uchun ishlatiladi);
status kamroq maydonlarni oʻz ichiga oladi.
| Usul | Yoʻl | Tavsif |
|---|---|---|
POST |
/api/services/cliproxy/install |
CLIProxyAPIʼni npm orqali oʻrnatish |
POST |
/api/services/cliproxy/start |
CLIProxyAPIʼni ishga tushirish |
POST |
/api/services/cliproxy/stop |
CLIProxyAPIʼni toʻxtatish |
POST |
/api/services/cliproxy/restart |
CLIProxyAPIʼni qayta ishga tushirish |
POST |
/api/services/cliproxy/update |
Yangiroq versiyaga yangilash |
GET |
/api/services/cliproxy/status |
Jonli + MB holati (apiKeyMasked mavjud emas) |
POST |
/api/services/cliproxy/auto-start |
Avtomatik ishga tushirishni yoqish/oʻchirish |
Umumiy GET /api/services/{name}/logs endpointi (§4.1 ga qarang) [name]
dinamik segmentidan foydalanib, barcha toʻrtta xizmat uchun ishlaydi.
Mux CLIProxyAPI bilan bir xil endpoint tuzilishiga ega — API sathida rotate-key
marshruti mavjud emas (bearer token 9Routerʼdagi kabi getOrCreateApiKey("mux")
orqali yaratiladi va MUX_SERVER_AUTH_TOKEN muhit oʻzgaruvchisi orqali kiritiladi,
ammo hozircha maxsus kalitni almashtirish endpointi mavjud emas). Mux faqat hayotiy
sikl doirasida boshqariladi: 9Routerʼdan farqli ravishda, unda 4-qatlam ijrochisi
mavjud emas va u hech qachon marshrutlash provayderi sifatida roʻyxatdan oʻtkazilmaydi.
| Usul | Yoʻl | Tavsif |
|---|---|---|
POST |
/api/services/mux/install |
Muxʼni npm orqali oʻrnatish (npm i mux) |
POST |
/api/services/mux/start |
Muxʼni ishga tushirish (mux server) |
POST |
/api/services/mux/stop |
Muxʼni toʻxtatish |
POST |
/api/services/mux/restart |
Muxʼni qayta ishga tushirish |
POST |
/api/services/mux/update |
Yangiroq npm versiyasiga yangilash |
GET |
/api/services/mux/status |
Jonli + MB holati |
POST |
/api/services/mux/auto-start |
Avtomatik ishga tushirishni yoqish/oʻchirish |
Bifrost — Go asosidagi AI shlyuz-releylari backendidir (@maximhq/bifrost). U
CLIProxyAPI bilan bir xil endpoint tuzilishidan foydalanadi (rotate-key mavjud
emas — Bifrost oʻz provayder kalitlarini -app-dir ichidagi config.json faylida
oʻzi boshqaradi).
| Usul | Yoʻl | Tavsif |
|---|---|---|
POST |
/api/services/bifrost/install |
Bifrostʼni npm orqali oʻrnatish (@maximhq/bifrost) |
POST |
/api/services/bifrost/start |
Bifrostʼni 8080-portda ishga tushirish (standart) |
POST |
/api/services/bifrost/stop |
Bifrostʼni toʻxtatish |
POST |
/api/services/bifrost/restart |
Bifrostʼni qayta ishga tushirish |
POST |
/api/services/bifrost/update |
Yangiroq versiyaga yangilash |
GET |
/api/services/bifrost/status |
Jonli + MB holati |
POST |
/api/services/bifrost/auto-start |
Avtomatik ishga tushirishni yoqish/oʻchirish |
GET |
/api/services/bifrost/logs |
SSE jurnal oxiri (umumiy [name]/logs dinamik marshruti orqali) |
Marshrutlash ulanishi: BIFROST_BASE_URL belgilanmagan va nazorat ostidagi
Bifrost nusxasi ishlayotgan boʻlsa, getBifrostRoutingConfig() (routingBackend.ts
ichida) avtomatik ravishda http://127.0.0.1:{port} manzilidan releyning asosiy
URL manzili sifatida foydalanadi. Aniq belgilangan BIFROST_BASE_URL muhit
oʻzgaruvchisi har doim ustunlikka ega.
Boshqa xizmatlar bilan bir xil hayotiy sikl tuzilishiga ega (install, start,
stop, restart, update, status, auto-start, auto-restart-adopted) hamda
admin/ ostida token bilan himoyalangan OAuth boshqaruv tekisligiga ega:
admin/accounts, admin/import-from-omniroute, admin/login-start,
admin/login-complete (barchasi DARIO_ADMIN_TOKEN bilan himoyalangan).
open-wa (@open-wa/wa-automate) WhatsApp Webʼni avtomatlashtirish uchun
interfeyssiz Chromium nusxasini (Puppeteer orqali) boshqaradi. U Mux bilan bir xil
endpoint tuzilishidan foydalanadi (rotate-key marshruti hozircha mavjud emas).
U faqat hayotiy sikl doirasida boshqariladi — marshrutlash nishoni emas hamda
4-qatlam ijrochisi/provayderi yozuviga ega emas.
| Metod | Yoʻl | Tavsif |
|---|---|---|
POST |
/api/services/openwa/install |
open-wa’ni npm (@open-wa/wa-automate) orqali oʻrnatish |
POST |
/api/services/openwa/start |
open-wa’ni 8323 portida ishga tushirish (standart) |
POST |
/api/services/openwa/stop |
open-wa’ni toʻxtatish |
POST |
/api/services/openwa/restart |
open-wa’ni qayta ishga tushirish |
POST |
/api/services/openwa/update |
Yangiroq versiyaga yangilash |
GET |
/api/services/openwa/status |
Joriy + DB holati |
POST |
/api/services/openwa/auto-start |
Avtomatik ishga tushirishni yoqish/oʻchirish |
GET |
/api/services/openwa/logs |
SSE jurnal davomi (umumiy [name]/logs dinamik marshruti orqali) |
API kaliti: WA_KEY sifatida kiritiladi — open-wa’ning umumiy WA_* prefiksli muhit o‘zgaruvchisini qayta belgilash mexanizmi uni --key/-k CLI parametriga moslaydi (dist/cli/setup.js::envArgs(), o‘rnatilgan 4.76.0 paketi bilan tekshirilgan). generateServiceApiKey() tomonidan yaratilganda ow_ prefiksi qoʻshiladi. open-wa kalitni key/api_key HTTP sarlavhasidan qayta oʻqiydi (Authorization: Bearer emas); /api-docs* tekshiruvdan bevosita ozod qilingan (dist/cli/server.js ichidagi setupAuthenticationLayer), shuning uchun holatni tekshirish soʻroviga autentifikatsiya sarlavhasi kerak emas.
Juftlash: open-wa norasmiy va WhatsApp bilan aloqador emas — ulangan raqam WhatsApp’ning avtomatlashtirishni aniqlash tizimi sababli bloklanish xavfiga ega. Birinchi marta ishga tushirilganda juftlash QR kodi stdout’ga chiqariladi va mavjud Jurnallar paneli/SSE oqimi orqali ko‘rsatiladi — bu integratsiyada hozircha QR tasviri uchun alohida endpoint mavjud emas.
Boshqaruv paneli 9Router veb interfeysini iframe ichiga quyidagi manzildagi ichki teskari proksi orqali joylashtiradi:
GET|POST|... /dashboard/providers/services/9router/embed/[...path]
Bu proksi:
- Soʻrovni
http://127.0.0.1:{port}/{path}manziliga yoʻnaltiradi (faqat loopback) - Kiruvchi
cookievaauthorizationsarlavhalarini olib tashlaydi (OmniRoute sessiyasi sizib chiqmaydi) - 9Router autentifikatsiyasi uchun
Authorization: Bearer {apiKey}sarlavhasini kiritadi - Javobdan
set-cookie,content-security-policy,x-frame-options,cross-origin-*sarlavhalarini olib tashlaydi <base href>elementini kiritish va mutlaq yoʻllarni normallashtirish uchun HTML javoblarini qayta yozadi (/foo→/dashboard/.../embed/foo)
Joylashtirilgan boshqaruv paneli uchun WebSocket yangilanishlari alohida portdagi yordamchi server tomonidan boshqariladi (src/lib/services/embedWsProxy.ts fayliga qarang).
Xavfsizlik: Joylashtirish proksi marshrutlari LOCAL_ONLY_API_PREFIXES tarkibida tasniflangan va ularga faqat loopback orqali kirish mumkin. Cloudflare/Ngrok tunneli orqali JWT olgan hujumchi joylashtirilgan xizmatlarga proksi orqali kira olmaydi.
/api/services/ va /dashboard/providers/services/*/embed/ ostidagi barcha yoʻnalishlar
src/server/authz/routeGuard.ts faylida LOCAL_ONLY sifatida tasniflangan. Loopback tekshiruvi
har qanday autentifikatsiya tarmogʻidan oldin, shartsiz bajariladi:
soʻrov keladi
→ isLocalOnlyPath(path)?
→ loopback emas → 403 LOCAL_ONLY (har doim, autentifikatsiya tekshiruvidan oldin)
→ loopback → odatiy autentifikatsiyaga oʻtish
Bu sizib chiqqan JWT (masalan, tunnel orqali) npm install ishga tushirishi yoki
jarayon yaratishining oldini oladi. Toʻliq darajalar matritsasi uchun
docs/security/ROUTE_GUARD_TIERS.md fayliga qarang.
9Router va Mux oʻz HTTP soʻnggi nuqtalari uchun API kaliti/bearer tokenini talab qiladi. OmniRoute:
- Xizmatga xos prefiks (
nr_— 9Router uchun,mx_— Mux uchun) bilancrypto.randomBytes(32).toString("base64url")orqali kalit yaratadi. - Uni AES-256-GCM yordamida saqlash vaqtida shifrlaydi (provayder hisob maʼlumotlari uchun ishlatiladigan ayni shifr).
- Jarayonni ishga tushirish vaqtida uni deshifrlaydi va muhit oʻzgaruvchisi sifatida
kiritadi — 9Router uchun
NINEROUTER_API_KEY, Mux uchunMUX_SERVER_AUTH_TOKEN(hech qachon CLI bayrogʻi sifatida emas, shuning uchun tokenps/jarayon roʻyxatlarida hech qachon koʻrinmaydi). - Hech qanday HTTP javobida ochiq matndagi kalitni qaytarmaydi.
CLIProxyAPI ishga tushirish vaqtida kiritiladigan maxsus maʼlumotlar tekisligi kalitini
oladi (needsApiKey: true — adapterga nisbatan model sinxronizatsiyasi uchun ishlatiladi).
Teskari HTTP proksi (/dashboard/.../embed/[...path]) soʻrovlarni faqat
http://127.0.0.1:{port} manziliga yoʻnaltirish uchun qatʼiy sozlangan. U loopback
boʻlmagan manzillarga qayta yoʻnaltirishlarni hech qachon kuzatmaydi.
ssrf-req-filter kutubxonasi loopback diapazonidan tashqaridagi manzilga aniqlanadigan
har qanday yuqori oqim URL manzilini rad etish uchun ishlatiladi.
npm install execFile('npm', ['install', pkg, '--prefix', dir]) orqali chaqiriladi —
shablon literallari, shell va tashqi yoʻllarni buyruq satriga interpolatsiya qilish
ishlatilmaydi. Ishlash vaqti qiymatlari (portlar, API kalitlari) bola jarayonning env
obyekti orqali uzatiladi.
/api/services/* dan qaytariladigan barcha xato javoblari buildErrorBody() yoki
sanitizeErrorMessage() orqali oʻtadi. Xom err.stack va err.message hech qachon
chaqiruvchiga aynan qaytarilmaydi.
Quyidagi 8 bosqichni bajaring. Kanonik namuna sifatida
src/lib/services/installers/ va src/app/api/services/ ichidagi mavjud
implementatsiyalarni oʻqing.
ninerouter.ts asosida modellashtirilgan src/lib/services/installers/{name}.ts
faylini yarating:
export const NAME_PACKAGE = "your-npm-package";
export const NAME_DEFAULT_PORT = 20132; // boʻsh portni tanlang
export async function install(version = "latest"): Promise<InstallResult> { ... }
export async function update(version = "latest"): Promise<InstallResult> { ... }
export async function uninstall(): Promise<void> { ... }
export function resolveSpawnArgs(apiKey: string, port: number): SpawnArgs { ... }
export async function getInstalledVersion(): Promise<string | null> { ... }
export async function getLatestVersion(): Promise<string | null> { ... }installers/utils.ts faylidagi runNpm(['install', NAME_PACKAGE, '--prefix', dir])
funksiyasidan foydalaning — hech qachon execSync yoki shell interpolatsiyasidan
foydalanmang.
src/lib/services/bootstrap.ts faylidagi SERVICES massiviga ServiceEntry qoʻshing:
{
tool: "myservice",
port: NAME_DEFAULT_PORT,
healthPath: "/health",
healthIntervalMs: 5_000,
stopTimeoutMs: 15_000,
logsBufferBytes: 5_242_880,
needsApiKey: true, // API kaliti kerak boʻlmasa false
}cfg.tool === "myservice" holatini qayta ishlashi uchun buildSpawnArgsFactory() ni
kengaytiring.
src/lib/services/providerPlugins/ bir xil backend shaklini oʻzaro bogʻliq boʻlmagan
ikkita alohida faylda ifodalash oʻrniga, backendning bootstrap.ts dagi ServiceEntry
maydonlari va serviceBackends.ts dagi manifest-shablon maydonlarini bitta obyektga
birlashtiruvchi ServiceProviderPlugin shartnomasini taqdim etadi. Ushbu matn yozilgan
paytda faqat 9router koʻchirilgan — bootstrap.ts oʻzining SERVICES[] yozuvini
getServiceProviderPlugin("9router") (src/lib/services/providerPlugins/registry.ts)
orqali hosil qiladi va plagin yoʻq boʻlsa, ishga tushirish xatosini chiqaradi. cliproxy,
mux va bifrost avvaldan mavjud ichki SERVICES[] literallarida oʻzgarishsiz qoladi.
open-sse/config/providerPluginManifest.ts shuningdek
SERVICE_BACKEND_MANIFEST_TEMPLATE yozuvidan toʻgʻri shakllangan
ProviderPluginManifestEntry yaratadigan qoʻshimcha
createServiceBackendManifestEntry(pluginId, template) yordamchi funksiyasiga ega
boʻldi — u hozircha hech qanday faol soʻrov yoʻliga ulanmagan
(generateProviderPluginManifestFromRegistry() ham, /v1/providers/[provider]/models
ham emas); shartnoma ikkinchi backend uchun isbotlangach, bu keyingi ish sifatida qoladi.
Keyingi PRlarga qoldirilgan va #7333 muammosi doirasida kuzatiladigan ishlar:
cliproxyapi ni xuddi shu reyestr orqali koʻchirish, mux/bifrost ni
ServiceBackendPluginId birlashmasiga umumlashtirish, bajaruvchi yoʻnaltirishining
maxsus holatlarini (open-sse/executors/index.ts,
open-sse/handlers/chatCore/executorProxy.ts) plagin shartnomasiga kiritish va
createServiceBackendManifestEntry() ni faol manifest/modellar kod yoʻliga ulash.
src/lib/db/migrations/ ichidagi migratsiya orqali xizmat version_manager jadvalida
qatorga ega ekanini taʼminlang. Qator quyidagicha boʻlishi kerak:
INSERT OR IGNORE INTO version_manager (tool, status, auto_start, provider_expose)
VALUES ('myservice', 'not_installed', 0, 0);src/app/api/services/{name}/ ostida:
_lib.ts getOrInitSupervisor() yordamchi funksiyasi
install/route.ts POST — installer.install() ni chaqiradi
start/route.ts POST — supervisor.start() ni chaqiradi
stop/route.ts POST — supervisor.stop() ni chaqiradi
restart/route.ts POST — supervisor.restart() ni chaqiradi
update/route.ts POST — installer.update() ni chaqiradi
status/route.ts GET — jonli + DB holatini birlashtiradi
auto-start/route.ts POST — auto_start bayrogʻini almashtiradi
Umumiy GET /api/services/[name]/logs marshruti allaqachon ulangan — u yerda hech qanday
oʻzgartirish kerak emas.
Barcha xato javoblarini createErrorResponse() / buildErrorBody() orqali qaytaring.
src/server/authz/routeGuard.ts faylida /api/services/ allaqachon roʻyxatga kiritilganini
tekshiring. Agar yangi prefiks kiritsangiz (masalan, /api/tools/), uni
LOCAL_ONLY_API_PREFIXES roʻyxatiga va, agar u jarayonlarni ishga tushirsa,
SPAWN_CAPABLE_PREFIXES roʻyxatiga ham qoʻshing.
tests/unit/authz/routeGuard.test.ts fayliga test qoʻshing.
src/app/(dashboard)/dashboard/providers/services/tabs/{Name}ServiceTab.tsx faylini yarating.
Umumiy komponentlardan qayta foydalaning:
ServiceStatusCard— real vaqtdagi holat + ishlash holati belgisiServiceLifecycleButtons— Ishga tushirish / Toʻxtatish / Qayta ishga tushirish / YangilashServiceLogsPanel— SSE jurnalining oxirgi yozuvlari (/api/services/{name}/logsmanziliga ulanadi)ApiKeyCard— kalitni koʻrsatish + almashtirish (agarneedsApiKey: trueboʻlsa)
Ichki oynani ServicesPageShell.tsx faylida roʻyxatdan oʻtkazing.
Agar ichki xizmat OpenAI bilan mos keluvchi /v1/chat/completions endpointini taqdim etsa:
src/shared/constants/providers.tsfayligaisEmbeddedService: truexususiyatiga ega provayder yozuvini qoʻshing.BaseExecutordan kengaytirilganopen-sse/executors/{name}.tsfaylini yarating. Har bir soʻrovda port va API kalitini qayta aniqlang (ularni konstruktorda hech qachon keshlamang). Nazoratchi holati"running"boʻlmasa,503 service_not_runningjavobini qaytaring.- Modellarni
open-sse/config/providerRegistry.tsfaylida xizmat prefiksi bilan (masalan,myservice/sub/model) roʻyxatdan oʻtkazing.modelSync.tsularni yangilab turadi.
docs/frameworks/EMBEDDED-SERVICES.mdfaylini (ushbu faylni) yangilang — xizmatni §1 dagi jadvalga, yangi endpointlarni esa §4 ga qoʻshing.tests/unit/services/ichiga modul testlarini qoʻshing (hayotiy sikl, oʻrnatuvchi, API shakli).tests/integration/services/ichiga integratsion test qoʻshing (RUN_SERVICES_INT=1orqali yoqiladi).docs/openapi.yamlfaylini yangi endpointlar bilan yangilang.
Alomatlar: Ishga tushirish tugmasi 503 kodini qaytaradi, holat "error" yoki "starting" bo‘lib qoladi.
Tekshiruv ro‘yxati:
GET /api/services/{name}/logsso‘rovini (yoki boshqaruv panelidagi Logs panelini) tekshiring.Error: ENOENT,address already in useyokiCannot find modulekabi qatorlarni qidiring.npmPATH ichida ekanini tekshiring: OmniRoute’ni ishga tushiradigan o‘sha foydalanuvchi hisobidanwhich npmbuyrug‘ini bajaring.- Xizmat o‘rnatilganini tekshiring:
installedVersionqiymatini ko‘rish uchunGET /api/services/{name}/statusso‘rovini tekshiring. Agar unullbo‘lsa, avval o‘rnatishni ishga tushiring. DATA_DIR/services/{name}/node_modules/mavjudligini va bo‘sh emasligini tekshiring.- Tozalangan chiqish sababini bilish uchun holat javobidagi
lastErrormaydonini tekshiring.
Alomatlar: Holat "running" yoki "error" holatiga o‘tishdan oldin uzoq vaqt "starting" bo‘lib qoladi.
Izoh: 9Router’ning sovuq ishga tushirilishi katta bog‘liqlik daraxtlarini (DNS, tunnel, MITM modullarini) import qilishni o‘z ichiga oladi. Standart sog‘lomlik tekshiruvi oralig‘i 2 s bo‘lib, nazoratchi vaqt tugaganini e’lon qilishidan oldin 3 marta urinadi (ammo so‘rovlarni davom ettiradi).
Yechim: healthIntervalMs va waitForHealthy kutish vaqti
(healthIntervalMs * 3) bootstrap.ts ichida sozlanadi. Ishga tushishi uzoqroq davom etadigan xizmatlar uchun healthIntervalMs qiymatini 5000 ga va stopTimeoutMs qiymatini 30 000 ga oshiring.
Alomatlar: Jurnallarda address already in use :::20130 ko‘rsatiladi.
Sabablar:
- Boshqa jarayon allaqachon 20130 portidan foydalanmoqda.
- Avvalgi 9Router jarayoni to‘liq to‘xtatilmagan (zombi PID).
Yechim:
.envichidagiNINEROUTER_PORTmuhit o‘zgaruvchisi orqali standart portni o‘zgartiring.- To‘qnashayotgan jarayonni toping va to‘xtating:
lsof -ti :20130 | xargs kill -9. - Port har bir xizmat uchun
bootstrap.tsichidagiportmaydoni orqali sozlanadi.
Eslatma: 9Router OmniRoute’ning standart 20128 porti bilan to‘qnashuvni oldini olish uchun aynan 20130 portidan foydalanadi.
Alomatlar: O‘rnatish 500 kodini qaytaradi, jurnallarda EACCES yoki permission denied ko‘rsatiladi.
Sabablar:
- OmniRoute jarayoni
DATA_DIRyoki uning ota katalogiga yoza olmaydi. - Docker ichida rootless rejimida, ulangan jildga yozish huquqisiz ishlatilmoqda.
Yechim:
DATA_DIRkatalogini tekshiring (standart:~/.omniroute/):ls -la ~/.omniroute/- Katalog OmniRoute jarayoni foydalanuvchisiga tegishli ekanini ta’minlang:
chown -R $USER ~/.omniroute/ - Docker’da jild ulanishi konteyner foydalanuvchisi uchun to‘g‘ri ruxsatlarga ega ekanini ta’minlang.
Alomatlar: Yangilash InstallError bilan 500 kodini qaytaradi, jurnallarda tarmoq kutish vaqti tugagani ko‘rsatiladi.
Tekshiruv ro‘yxati:
- npm reyestriga ulanish mumkinligini tasdiqlang:
npm ping. - Korporativ proksi mavjudligini tekshiring:
npm config get proxy,npm config get https-proxy. - O‘rnatishni qo‘lda sinab ko‘ring:
npm install {package}@latest --prefix ~/.omniroute/services/{name}/. - Agar tarmoqdan uzilgan muhitda bo‘lsangiz, tarball faylini oldindan yuklab oling va
npm install /path/to/tarball.tgzbuyrug‘idan foydalaning.
Alomatlar: Holat 5 soniyadan kamroq vaqt ichida "starting" holatidan "error" holatiga o‘tadi.
lastError maydonida "Fast crash (exited with code 1)" ko‘rsatiladi.
Tekshiruv ro‘yxati:
- Jurnalning to‘liq oxirgi qismini o‘qing:
GET /api/services/{name}/logs?tail=500. - Keng tarqalgan sabab: xizmat kutayotgan muhit o‘zgaruvchilarining mavjud emasligi.
- 9Router uchun:
NINEROUTER_DISABLE_MITM=truevaNINEROUTER_DISABLE_TUNNEL=truejarayonni yaratishda uzatiladigan muhit tarkibida ekanini tekshiring (installers/ninerouter.tsichidagiresolveSpawnArgsbo‘limiga qarang).
Savol: Oʻrnatilgan xizmatlarning endpointlarini loopback boʻlmagan mijozlarga ochishim mumkinmi?
Yoʻq. LOCAL_ONLY darajasi ataylab shunday belgilangan (qatʼiy qoida #17). npm install buyrugʻini ishga tushirishi yoki node jarayonlarini yaratishi mumkin boʻlgan marshrutlar loopback boʻlmagan trafikdan ochiq boʻlmasligi kerak, chunki tunnel (Cloudflare, Ngrok, Tailscale) orqali JWT sizib chiqsa, aks holda bu ixtiyoriy jarayonlarni yaratish imkonini beradi. /api/services/ uchun istisno tariqasida voz kechish imkoniyati yoʻq — /api/mcp/ dan farqli ravishda, u manage-scope chetlab oʻtish roʻyxatiga kiritilmagan. docs/security/ROUTE_GUARD_TIERS.md fayliga qarang.
Savol: 9Router va CLIProxyAPI production/bulut muhitlarida mavjud boʻladimi?
Ha. Har ikkala xizmat ham OmniRoute kabi bir xil local-first modeliga amal qiladi. Ular ayni bir mashinada ishlaydi va loopback orqali aloqa qiladi. Bu yerda "Production" masofaviy bulut provayderini emas, balki OmniRoute joylashtirilgan VPS yoki mahalliy serverni anglatadi.
Savol: Supervisorʼni qanday disk raskadrovka qilishim mumkin?
- SSE jurnal oqimining oxirgi qismini kuzating:
curl -N http://localhost:20128/api/services/9router/logs. - OmniRouteʼning pino chiqishidagi
service:supervisornamespace boʻyicha filtrlangan tuzilmaviy jurnallarni tekshiring. - DB qatorini tekshiring:
sqlite3 ~/.omniroute/omniroute.db "SELECT * FROM version_manager WHERE tool='9router'". - Joriy real vaqtdagi holat, PID, xizmat salomatligi va
lastErrorqiymatini bitta soʻrovda koʻrish uchunGET /api/services/9router/statusdan foydalaning.
Savol: Supervisor health: "degraded" yoki health: "unknown" ni koʻrsatmoqda, ammo holat "running". Bu muammomi?
"degraded" salomatlik tekshiruvi 200 dan boshqa javob qaytarganini anglatadi. "unknown" hali hech qanday tekshiruv yakunlanmaganini anglatadi (birinchi soʻrov bilan poyga holati). Ishga tushirish vaqtida har ikkala holat ham vaqtinchalikdir. Agar "running" holatidan keyin salomatlik healthIntervalMs * 3 ms dan koʻproq vaqt davomida "degraded" boʻlib qolsa, oʻrnatilgan xizmat ishlayotgan, ammo uning HTTP APIʼsi javob bermayotgan boʻladi. Holat javobidagi port toʻgʻri ekanini va xizmat haqiqatda shu portni tinglayotganini tekshiring.
Savol: 9Router API kalitini toʻliq qayta ishga tushirmasdan oʻzgartirishim mumkinmi?
Yoʻq. API kaliti jarayon yaratilayotgan vaqtda muhit oʻzgaruvchisi orqali 9Routerʼga uzatiladi. Ishlayotgan jarayonda muhit oʻzgaruvchilarini oʻzgartirib boʻlmaydi. POST .../rotate-key yangi kalitni qoʻllash uchun xizmatni avtomatik ravishda toʻxtatadi va qayta ishga tushiradi. Kalitni almashtirish xizmatning stopTimeoutMs muddati (standart qiymati 15 s) va uning ishga tushish vaqti yigʻindisi ichida kuchga kiradi.
Savol: Halqali bufer cheklovi qancha va u toʻlganda nima sodir boʻladi?
Har bir xizmat uchun alohida 5 MB hajmli halqali bufer mavjud. Bufer toʻlganda, yangi qatorlar uchun joy boʻshatish maqsadida eng eski jurnal qatorlari chiqarib tashlanadi. SSE snapshot hodisasi tail chegarasi doirasidagi eng soʻnggi qatorlarni qaytaradi. DB qatorida logsBufferPath belgilanmagan boʻlsa, jurnallar diskda saqlanmaydi.
docs/security/ROUTE_GUARD_TIERS.md— LOCAL_ONLY darajasi tafsilotlaridocs/architecture/CODEBASE_DOCUMENTATION.md— §3.2 Oʻrnatilgan xizmatlar modulining xaritalanishidocs/architecture/ARCHITECTURE.md— tizim darajasidagi kontekstdocs/openapi.yaml— mashina oʻqiy oladigan endpoint taʼriflariCLAUDE.md§"Adding a New Embedded Service" — tezkor maʼlumot uchun nazorat roʻyxati