🌐 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 · 🇲🇾 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 · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
आवृत्ती: v3.8.44 शेवटचे अद्यतन: 2026-09-09 लक्ष्यित वाचक: एम्बेडेड सेवा (9Router, CLIProxyAPI, Mux, Bifrost, open-wa) जोडणारे, त्यांची देखभाल करणारे किंवा त्यांतील त्रुटी शोधणारे अभियंते.
एम्बेडेड सेवा ही स्थानिकरीत्या स्थापित केलेली प्रोसेस साइडकार साधने आहेत, जी OmniRoute स्थापित करते, त्यांचे पर्यवेक्षण करते आणि त्यांना प्रथम-श्रेणी रूटिंग लक्ष्ये म्हणून उपलब्ध करून देते. बाह्य प्रदात्यांप्रमाणे (ज्यांच्याशी इंटरनेटवरून API की वापरून संपर्क साधला जातो) नसून, एम्बेडेड सेवा OmniRoute असलेल्या त्याच मशीनवर चालतात आणि लूपबॅकद्वारे संवाद साधतात.
- आढावा
- आर्किटेक्चर — 4 स्तर
- लाइफसायकल स्थिती यंत्र
- API संदर्भ
- सुरक्षा
- नवीन एम्बेडेड सेवा जोडणे
- समस्यानिवारण
- वारंवार विचारले जाणारे प्रश्न
सहा सेवा एम्बेड केलेल्या आहेत:
| सेवा | npm पॅकेज | डीफॉल्ट पोर्ट | उद्देश |
|---|---|---|---|
| 9Router | 9router |
20130 | OmniRoute उप-प्रदाता म्हणून वापरू शकणारा AI राउटर. मॉडेल्स 9router/{sub}/{model} या स्वरूपात उपलब्ध केली जातात |
| CLIProxyAPI | GitHub रिलीज बायनरी (cliproxy) |
8317 | Anthropic CLI प्रमाणीकरण प्रवाहांसाठी स्थानिक प्रॉक्सी अडॅप्टर. OAuth टोकन कालबाह्य झाल्यावर फॉलबॅक राउटिंग प्रदान करतो |
| Mux | mux (हेडलेस mux server) |
8322 | स्थानिक एजंट-ऑर्केस्ट्रेशन डीमन (coder/mux). केवळ जीवनचक्र-व्यवस्थापित — राउटिंग लक्ष्य नाही (LLM प्रॉक्सीइंग नाही). |
| Bifrost | @maximhq/bifrost |
8080 | Go AI-गेटवे रिले बॅकएंड. सुरू असताना, रिले रूटद्वारे (/v1/relay/) स्वयंचलितपणे निवडला जातो |
| Dario | @askalf/dario |
3456 | Claude-सदस्यता प्रॉक्सी — Claude-Code-स्वरूपाच्या ट्रॅफिकसाठी CLIProxyAPI चा पर्याय/फेलओव्हर; इंजेक्ट केलेली की DARIO_ADMIN_TOKEN बनते आणि त्याच्या /admin/* OAuth नियंत्रण स्तराचे संरक्षण करते |
| open-wa | @open-wa/wa-automate |
8323 | WhatsApp Web स्वयंचलन (Puppeteer द्वारे हेडलेस Chromium). केवळ जीवनचक्र-व्यवस्थापित — राउटिंग लक्ष्य नाही. |
सर्व सहा सेवा समान पर्यवेक्षी मॉडेलचे अनुसरण करतात:
- OmniRoute त्यांना
DATA_DIR/services/{name}/अंतर्गत स्थापित करते (OmniRoute च्या स्वतःच्याpackage.jsonपासून विलग) - OmniRoute त्यांना चाइल्ड प्रोसेस म्हणून सुरू करते आणि त्यांचे निरीक्षण करते
- OmniRoute चाइल्ड प्रोसेसच्या वातावरणात तात्पुरती API की इंजेक्ट करते आणि सेवा बंद न करता ती बदलते (लागू असेल तेथे)
- सर्व व्यवस्थापन रूट्स (
/api/services/*) LOCAL_ONLY आहेत — केवळ लूपबॅकवरून प्रवेशयोग्य (कठोर नियम #17)
| निर्णय | मूल्य |
|---|---|
| 9Router च्या मूळ UI साठी डॅशबोर्ड प्रवेश | /dashboard/providers/services/9router/embed/* येथे रिव्हर्स प्रॉक्सी |
| स्थापना यंत्रणा | execFile द्वारे npm install {package} (शेल इंटरपोलेशन नाही) |
| वापर पद्धत | राउटिंग इंजिनमध्ये 9router/{sub}/{model} म्हणून नोंदणीकृत प्रदाता |
| API की व्यवस्थापन | OmniRoute व्युत्पन्न करते, स्थिर संचयनात एन्क्रिप्ट करते (AES-256-GCM) आणि env द्वारे इंजेक्ट करते |
| डॅशबोर्ड स्थान | /dashboard/providers/services (तीन टॅब) |
| स्वयंचलित प्रारंभ | प्रत्येक सेवेसाठी टॉगल, डीफॉल्टनुसार बंद |
┌────────────────────────────────────────────────────────────────────┐
│ स्तर 1 — UI │
│ /dashboard/providers/services (टॅब: CLIProxyAPI | 9Router | Mux)│
│ थेट लॉग (SSE), सुरू/थांबवा/रीस्टार्ट/अपडेट, सेटिंग्ज, इंस्टॉल │
│ │
│ src/app/(dashboard)/dashboard/providers/services/ │
│ ├── page.tsx Shell + ?tab= द्वारे टॅब रूटिंग │
│ ├── tabs/ CliproxyServiceTab, NinerouterServiceTab,│
│ │ MuxServiceTab │
│ └── components/ ServiceStatusCard, ServiceLifecycleButtons,│
│ ServiceLogsPanel, ApiKeyCard, ... │
└──────────────────────┬─────────────────────────────────────────────┘
│ HTTP (Next.js fetch)
┌──────────────────────▼─────────────────────────────────────────────┐
│ स्तर 2 — API (LOCAL_ONLY — फक्त लूपबॅक) │
│ │
│ /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] │
│ (रिव्हर्स HTTP + WebSocket प्रॉक्सी → 9Router अपस्ट्रीम) │
│ │
│ गेट: LOCAL_ONLY_API_PREFIXES मध्ये "/api/services/" आणि │
│ "/dashboard/providers/services/*/embed/" समाविष्ट आहेत │
└──────────────────────┬─────────────────────────────────────────────┘
│ प्रक्रियेतील कॉल
┌──────────────────────▼─────────────────────────────────────────────┐
│ स्तर 3 — ServiceSupervisor (src/lib/services/) │
│ │
│ ServiceSupervisor.ts सर्वसाधारण सुपरवायझर (child_process.spawn)│
│ ├── इंस्टॉल: execFile('npm', ['install', pkg, '--prefix']) │
│ ├── प्रारंभ: spawn(node, [entrypoint], {env, cwd}) │
│ ├── api_key: crypto.randomBytes(32) → env NINEROUTER_API_KEY │
│ ├── पोर्ट: 9Router साठी 20130 (कॉन्फिगर करण्यायोग्य) │
│ ├── लॉग: stdio रिंग बफर 5 MB → SSE इव्हेंट्स │
│ ├── आरोग्य: दर 2–5 सेकंदांनी HTTP GET /health, आळशी पुनर्प्राप्ती│
│ └── जीवनचक्र: SIGTERM 15 सेकंद → SIGKILL │
│ │
│ registry.ts getSupervisor(name) / registerSupervisor() │
│ bootstrap.ts प्रक्रिया सुरू होताना सर्व SERVICES[] बूटस्ट्रॅप करते│
│ apiKey.ts getOrCreateApiKey(), generateServiceApiKey() │
│ modelSync.ts नियतकालिक GET /v1/models → service_models टेबल│
│ ringBuffer.ts वर्तुळाकार लॉग बफर (प्रत्येक सेवेसाठी 5 MB) │
│ healthCheck.ts पोलिंग HTTP आरोग्य तपासणी │
│ installers/ ninerouter.ts, cliproxy.ts, mux.ts, openwa.ts │
│ (इंस्टॉलर अॅडॅप्टर) │
└──────────────────────┬─────────────────────────────────────────────┘
│ OpenAI-सुसंगत HTTP (लूपबॅक)
┌──────────────────────▼─────────────────────────────────────────────┐
│ स्तर 4 — प्रदाता / रूटिंग │
│ │
│ open-sse/executors/ninerouter.ts │
│ प्रत्येक विनंतीसाठी पोर्ट आणि API की पुन्हा शोधते (कॅशिंग नाही).│
│ प्रॉक्सी करण्यापूर्वी मॉडेल आयडीमधून "9router/" उपसर्ग काढते. │
│ सुपरवायझर "running" स्थितीत नसल्यास 503 service_not_running परत करते.│
│ │
│ src/shared/constants/providers.ts │
│ "9router" साठी नोंद: isEmbeddedService: true │
│ │
│ open-sse/config/providerRegistry.ts │
│ मॉडेल्स "9router/{sub}/{model}" म्हणून साठवली जातात (उपसर्गासह).│
│ modelSync.ts द्वारे दर 5 मिनिटांनी समक्रमित केली जातात. │
│ │
│ Mux चे फक्त जीवनचक्र व्यवस्थापित केले जाते (स्तर 1-3) — ते एजंट- │
│ ऑर्केस्ट्रेशन डेमन आहे, LLM प्रॉक्सी नाही; त्यामुळे त्यासाठी स्तर 4│
│ executor/provider नोंद नाही आणि ते कधीही रूटिंग लक्ष्य नसते. │
└────────────────────────────────────────────────────────────────────┘
| फाइल | भूमिका |
|---|---|
src/lib/services/ServiceSupervisor.ts |
मुख्य क्लास: जीवनचक्र, लॉक, आरोग्य, रिंग बफर |
src/lib/services/bootstrap.ts |
प्रोसेस-स्तरीय नोंदणी आणि स्वयंचलित प्रारंभ |
src/lib/services/registry.ts |
सिंगलटन मॅप tool → supervisor |
src/lib/services/apiKey.ts |
की निर्मिती, स्थिर डेटासाठी AES-256-GCM एन्क्रिप्शन |
src/lib/services/modelSync.ts |
नियतकालिक मॉडेल समक्रमण (5 मिनिटे) + मागणीनुसार |
src/lib/services/ringBuffer.ts |
SSE सदस्यत्वासह 5 MB वर्तुळाकार लॉग बफर |
src/lib/services/healthCheck.ts |
HTTP आरोग्य तपासणी (कॉन्फिगर करता येणारे मध्यांतर) |
src/lib/services/installers/ninerouter.ts |
9Router साठी npm इंस्टॉल/अपडेट/अनइंस्टॉल |
src/lib/services/installers/cliproxy.ts |
CLIProxyAPI साठी npm इंस्टॉल/अपडेट/अनइंस्टॉल |
src/lib/services/installers/mux.ts |
Mux साठी npm इंस्टॉल/अपडेट/अनइंस्टॉल |
src/lib/services/installers/openwa.ts |
open-wa साठी npm इंस्टॉल/अपडेट/अनइंस्टॉल |
src/app/api/services/9router/_lib.ts |
getOrInitSupervisor() सहाय्यक |
src/app/api/services/[name]/logs/route.ts |
सामायिक SSE लॉग्स एंडपॉइंट |
open-sse/executors/ninerouter.ts |
प्रदाता एक्झिक्युटर (स्तर 4) |
install()
┌─────────────┐ ──────────► ┌─────────────┐
│ not_installed│ │ stopped │◄──────────────────┐
└─────────────┘ └──────┬──────┘ │
│ start() │
▼ │ stop()
┌──────────┐ │
│ starting │ │
└────┬─────┘ │
हेल्थ प्रोब यशस्वी │ क्रॅश / SIGTERM │
┌────▼─────┐ (5s आत एक्झिट) │
│ running │──── क्रॅश ──────────►┤
└────┬─────┘ ┌─▼────┐
stop() │ │error │
▼ └──────┘
┌──────────┐
│ stopping │
└──────────┘
स्थिती version_manager DB तक्त्यात (status स्तंभ) संग्रहित केली जाते आणि
ServiceSupervisor च्या इन-मेमरी स्थितीत प्रतिबिंबित केली जाते. चालू प्रक्रियेसाठी
इन-मेमरी स्थिती अधिकृत असते; बूटच्या वेळी DB स्थिती टिकाऊ फॉलबॅक असते.
| येथून | घटना | येथे |
|---|---|---|
not_installed |
install() यशस्वी होते |
stopped |
stopped |
start() कॉल केले जाते |
starting |
starting |
हेल्थ प्रोब 200 परत करतो | running |
starting |
निरोगी होण्यापूर्वी प्रक्रिया बंद होते | error |
running |
stop() कॉल केले जाते |
stopping → stopped |
running |
प्रक्रिया अनपेक्षितपणे बंद होते (< 5 s) | error (जलद क्रॅश) |
running |
प्रक्रिया अनपेक्षितपणे बंद होते (> 5 s) | error |
error |
start() कॉल केले जाते |
starting |
| कोणतीही | stopping असताना stop() |
कोणतीही कृती नाही |
ServiceSupervisor असिंक्रोनस ऑपरेशन लॉकद्वारे (withLock()) लाइफसायकल ऑपरेशन्स
क्रमबद्ध करतो. एकाच सुपरवायझरवरील समवर्ती start() कॉल्समुळे नेमकी एकच प्रक्रिया
स्पॉन होते; दुसरा कॉलर प्रतीक्षा करतो आणि विद्यमान स्थिती परत करतो. उदाहरणार्थ,
ऑटो-स्टार्ट आणि UI बटण एकाच वेळी सक्रिय झाल्यास यामुळे रेस कंडिशन्स टाळल्या जातात.
/api/services/ अंतर्गत असलेले सर्व मार्ग LOCAL_ONLY आहेत (केवळ loopback, कठोर नियम #17).
auth token कोणताही असला तरी non-loopback विनंत्यांना 403 LOCAL_ONLY मिळतो.
npm वरून 9Router स्थापित करते. स्वतःचे package.json आणि node_modules/ असलेली
DATA_DIR/services/9router/ निर्देशिका तयार करते. OmniRoute च्या स्वतःच्या deps सोबत संघर्ष होत नाही.
विनंतीचे body (सर्व पर्यायी):
{ "version": "latest" }| फील्ड | प्रकार | डीफॉल्ट | वर्णन |
|---|---|---|---|
version |
string |
"latest" |
स्थापित करण्यासाठी npm version tag किंवा semver |
प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
{ ok: true, installedVersion: "x.y.z", path: "..." } |
400 |
अवैध विनंती body (Zod प्रमाणीकरण अयशस्वी) |
409 |
स्थापना आधीपासून सुरू आहे (lock धरलेले आहे) |
500 |
npm install अयशस्वी — अनुकूल त्रुटी संदेशासाठी message पाहा |
टिपा: execFile('npm', [...]) वापरते — shell नाही, interpolation नाही (कठोर नियम #13).
EACCES त्रुटी अनुकूल संदेशांच्या स्वरूपात दाखवल्या जातात.
9Router सुरू करते. supervisor आधीपासून नोंदणीकृत नसल्यास त्याची नोंदणी करते आणि त्यानंतर
supervisor.start() कॉल करते. आधीच चालू असताना idempotent असते.
विनंतीचे body: नाही
प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
ServiceStatus object (खालील schema पाहा) |
409 |
9Router स्थापित केलेले नाही (status: "not_installed") |
503 |
सुरू करणे अयशस्वी (process त्रुटी — lastError पाहा) |
ServiceStatus schema:
{
"tool": "9router",
"state": "running",
"pid": 12345,
"port": 20130,
"health": "healthy",
"startedAt": "2026-05-25T10:00:00.000Z",
"lastError": null
}9Router व्यवस्थितपणे थांबवते. SIGTERM पाठवते, 15 s प्रतीक्षा करते आणि तरीही चालू असल्यास SIGKILL पाठवते. आधीच थांबलेले असताना idempotent असते.
विनंतीचे body: नाही
प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
ServiceStatus (state: "stopped") |
503 |
थांबवणे अनपेक्षितपणे अयशस्वी झाले |
operation lock अंतर्गत stop() आणि त्यानंतर start() करण्याच्या समतुल्य.
विनंतीचे body: नाही
प्रतिसाद: start प्रमाणेच (अंतिम ServiceStatus परत करते).
9Router अधिक नवीन npm version वर update करते. service चालू असल्यास, प्रथम ती थांबवली जाते, npm install चालवले जाते (नवीन version त्याच ठिकाणी स्थापित करून) आणि त्यानंतर service पुन्हा सुरू केली जाते.
विनंतीचे body (सर्व पर्यायी):
{ "version": "latest" }प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
{ ok: true, previousVersion: "...", installedVersion: "..." } |
400 |
अवैध body |
500 |
npm update अयशस्वी |
9Router साठी नवीन API key निर्माण करते, तो at-rest encrypt करते आणि service (चालू असल्यास) पुन्हा सुरू करते, जेणेकरून ती तिच्या environment मधून नवीन key घेईल. जुना key तात्काळ अवैध केला जातो.
विनंतीचे body: नाही
प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
{ keyRotated: true, restarted: boolean } |
500 |
rotation अयशस्वी |
सुरक्षा: नवीन key प्रतिसादात कधीही परत केला जात नाही (credential leak नाही).
तो version_manager table मध्ये encrypted (AES-256-GCM) स्वरूपात संग्रहित केला जातो.
version metadata आणि API key preview यांच्यासह एकत्रित live + DB स्थिती परत करते.
प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
खालील schema पाहा |
500 |
स्थिती वाचणे अयशस्वी |
प्रतिसाद schema:
{
"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
}auto-start flag toggle करते. enabled: true असताना, पुढील वेळी OmniRoute boot झाल्यावर
service आपोआप सुरू होते (service स्थापित केलेली असल्यास).
विनंतीचे body:
{ "enabled": true }प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
{ autoStart: true } |
400 |
अवैध body |
9Router च्या stdout/stderr ring buffer मधील live logs चा SSE stream.
Query parameters:
| parameter | प्रकार | डीफॉल्ट | वर्णन |
|---|---|---|---|
tail |
integer |
200 | सुरुवातीला किती historical lines पाठवायच्या (कमाल 1000) |
filter |
string |
नाही | Case-insensitive substring filter (regex नाही — ReDoS-सुरक्षित) |
SSE events:
| Event | Data | वर्णन |
|---|---|---|
snapshot |
LogLine[] |
सुरुवातीचा historical tail |
log |
LogLine |
Live log line |
heartbeat |
{} |
प्रत्येक 15 s नंतर keep-alive |
LogLine schema:
{
"ts": 1716633600000,
"stream": "stdout",
"line": "[9router] Listening on :20130"
}प्रतिसाद:
| स्थिती | वर्णन |
|---|---|
200 |
text/event-stream |
400 |
filter पॅरामीटर खूप मोठा (> 200 वर्ण) |
404 |
सेवा आढळली नाही (supervisor नोंदणीकृत नाही) |
CLIProxyAPI च्या एंडपॉइंट्सची रचना 9Router सारखीच आहे, फक्त rotate-key वगळून आणि
accounts, provider-expose व auto-restart-adopted समाविष्ट करून. आता त्याला
spawn वेळी इंजेक्ट केलेली समर्पित data-plane API key मिळते (bootstrap.ts मध्ये
needsApiKey: true, जी मॉडेल सिंकसाठी वापरली जाते); status मध्ये कमी फील्ड्स समाविष्ट आहेत.
| पद्धत | मार्ग | वर्णन |
|---|---|---|
POST |
/api/services/cliproxy/install |
npm वरून CLIProxyAPI इंस्टॉल करा |
POST |
/api/services/cliproxy/start |
CLIProxyAPI सुरू करा |
POST |
/api/services/cliproxy/stop |
CLIProxyAPI थांबवा |
POST |
/api/services/cliproxy/restart |
CLIProxyAPI रीस्टार्ट करा |
POST |
/api/services/cliproxy/update |
नवीन आवृत्तीवर अपडेट करा |
GET |
/api/services/cliproxy/status |
लाइव्ह + DB स्थिती (apiKeyMasked शिवाय) |
POST |
/api/services/cliproxy/auto-start |
स्वयंचलित प्रारंभ टॉगल करा |
सामायिक GET /api/services/{name}/logs एंडपॉइंट (§4.1 पाहा) [name] डायनॅमिक
सेगमेंट वापरून सर्व चार सेवांसाठी कार्य करतो.
Mux च्या एंडपॉइंट्सची रचना CLIProxyAPI सारखीच आहे — API पृष्ठभागावर rotate-key
मार्ग नाही (bearer token हा 9Router प्रमाणेच getOrCreateApiKey("mux") द्वारे
निर्माण केला जातो आणि MUX_SERVER_AUTH_TOKEN env var द्वारे इंजेक्ट केला जातो, परंतु
अद्याप कोणताही समर्पित rotation एंडपॉइंट नाही). Mux केवळ lifecycle-managed आहे:
9Router च्या विपरीत, त्यामध्ये Layer 4 executor नाही आणि routing provider म्हणून
त्याची कधीही नोंदणी केली जात नाही.
| पद्धत | मार्ग | वर्णन |
|---|---|---|
POST |
/api/services/mux/install |
npm वरून Mux इंस्टॉल करा (npm i mux) |
POST |
/api/services/mux/start |
Mux सुरू करा (mux server) |
POST |
/api/services/mux/stop |
Mux थांबवा |
POST |
/api/services/mux/restart |
Mux रीस्टार्ट करा |
POST |
/api/services/mux/update |
नवीन npm आवृत्तीवर अपडेट करा |
GET |
/api/services/mux/status |
लाइव्ह + DB स्थिती |
POST |
/api/services/mux/auto-start |
स्वयंचलित प्रारंभ टॉगल करा |
Bifrost हा Go AI-gateway relay backend (@maximhq/bifrost) आहे. तो CLIProxyAPI
सारखीच एंडपॉइंट रचना वापरतो (rotate-key नाही — Bifrost स्वतःच्या provider keys
त्याच्या -app-dir अंतर्गत config.json मध्ये व्यवस्थापित करतो).
| पद्धत | मार्ग | वर्णन |
|---|---|---|
POST |
/api/services/bifrost/install |
npm वरून Bifrost इंस्टॉल करा (@maximhq/bifrost) |
POST |
/api/services/bifrost/start |
पोर्ट 8080 वर Bifrost सुरू करा (डीफॉल्ट) |
POST |
/api/services/bifrost/stop |
Bifrost थांबवा |
POST |
/api/services/bifrost/restart |
Bifrost रीस्टार्ट करा |
POST |
/api/services/bifrost/update |
नवीन आवृत्तीवर अपडेट करा |
GET |
/api/services/bifrost/status |
लाइव्ह + DB स्थिती |
POST |
/api/services/bifrost/auto-start |
स्वयंचलित प्रारंभ टॉगल करा |
GET |
/api/services/bifrost/logs |
SSE लॉग टेल (सामायिक [name]/logs डायनॅमिक मार्गाद्वारे) |
रूटिंग जोडणी: BIFROST_BASE_URL सेट नसताना आणि supervised Bifrost instance
चालू असताना, getBifrostRoutingConfig() (routingBackend.ts मध्ये) आपोआप
http://127.0.0.1:{port} चा relay base URL म्हणून वापर करते. स्पष्टपणे सेट केलेल्या
BIFROST_BASE_URL env ला नेहमी प्राधान्य दिले जाते.
इतर सेवांसारखीच lifecycle रचना (install, start, stop, restart,
update, status, auto-start, auto-restart-adopted), तसेच admin/ अंतर्गत
token-gated OAuth control plane: admin/accounts, admin/import-from-omniroute,
admin/login-start, admin/login-complete (सर्व DARIO_ADMIN_TOKEN च्या संरक्षणाखाली).
open-wa (@open-wa/wa-automate) WhatsApp Web स्वयंचलित करण्यासाठी headless
Chromium instance (Puppeteer द्वारे) चालवते. ते Mux सारखीच एंडपॉइंट रचना वापरते
(अद्याप rotate-key मार्ग नाही). ते केवळ lifecycle-managed आहे — routing target
नाही आणि कोणतीही Layer 4 executor/provider नोंद नाही.
| पद्धत | मार्ग | वर्णन |
|---|---|---|
POST |
/api/services/openwa/install |
npm वरून open-wa (@open-wa/wa-automate) स्थापित करते |
POST |
/api/services/openwa/start |
पोर्ट 8323 वर open-wa सुरू करते (डीफॉल्ट) |
POST |
/api/services/openwa/stop |
open-wa थांबवते |
POST |
/api/services/openwa/restart |
open-wa रीस्टार्ट करते |
POST |
/api/services/openwa/update |
नवीन आवृत्तीवर अपडेट करते |
GET |
/api/services/openwa/status |
लाइव्ह + DB स्थिती |
POST |
/api/services/openwa/auto-start |
स्वयंचलित प्रारंभ टॉगल करते |
GET |
/api/services/openwa/logs |
SSE लॉग टेल (सामायिक [name]/logs डायनॅमिक रूटद्वारे) |
API की: WA_KEY म्हणून अंतःक्षेपित केली जाते — open-wa चे सर्वसाधारण WA_*-उपसर्ग असलेले env
ओव्हरराइड तिला --key/-k CLI पर्यायाशी मॅप करते
(dist/cli/setup.js::envArgs(), स्थापित 4.76.0
पॅकेजच्या तुलनेत पडताळलेले). generateServiceApiKey() द्वारे तयार केल्यावर ow_ उपसर्ग लावला जातो. open-wa
ही की key/api_key HTTP हेडरमधून परत वाचते (Authorization: Bearer मधून नाही); /api-docs* ला या तपासणीतून स्पष्टपणे वगळले आहे
(dist/cli/server.js मधील setupAuthenticationLayer), त्यामुळे हेल्थ प्रोबसाठी
ऑथ हेडरची आवश्यकता नाही.
पेअरिंग: open-wa हे अनधिकृत असून WhatsApp शी संलग्न नाही — कनेक्ट केलेल्या क्रमांकावर WhatsApp च्या स्वतःच्या ऑटोमेशन शोध प्रणालीमुळे बंदीचा धोका असतो. पहिल्यांदा सुरू केल्यावर, पेअरिंग QR कोड stdout वर प्रिंट केला जातो आणि विद्यमान लॉग पॅनेल/SSE स्ट्रीमद्वारे उपलब्ध केला जातो — या इंटिग्रेशनमध्ये अद्याप स्वतंत्र QR-प्रतिमा एंडपॉइंट नाही.
डॅशबोर्ड अंतर्गत रिव्हर्स प्रॉक्सीद्वारे 9Router वेब UI iframe मध्ये एम्बेड करतो:
GET|POST|... /dashboard/providers/services/9router/embed/[...path]
हा प्रॉक्सी:
- विनंती
http://127.0.0.1:{port}/{path}कडे फॉरवर्ड करतो (केवळ लूपबॅक) - येणारे
cookieआणिauthorizationहेडर काढून टाकतो (OmniRoute सेशनची गळती होत नाही) - 9Router प्रमाणीकरणासाठी
Authorization: Bearer {apiKey}अंतःक्षेपित करतो - प्रतिसादातून
set-cookie,content-security-policy,x-frame-options,cross-origin-*काढून टाकतो <base href>अंतःक्षेपित करण्यासाठी आणि अॅब्सोल्यूट पाथ सामान्यीकृत करण्यासाठी (/foo→/dashboard/.../embed/foo) HTML प्रतिसाद पुनर्लिखित करतो
एम्बेड केलेल्या डॅशबोर्डसाठी WebSocket अपग्रेड स्वतंत्र पोर्टवरील
पूरक सर्व्हरद्वारे हाताळले जातात (src/lib/services/embedWsProxy.ts पहा).
सुरक्षा: एम्बेड प्रॉक्सी रूट्सना LOCAL_ONLY_API_PREFIXES अंतर्गत वर्गीकृत केले आहे
आणि त्यांना केवळ लूपबॅकवरून प्रवेश करता येतो. Cloudflare/Ngrok टनेलद्वारे
JWT मिळवणारा हल्लेखोर एम्बेड केलेल्या सेवांमध्ये प्रॉक्सी करू शकत नाही.
/api/services/ आणि /dashboard/providers/services/*/embed/ अंतर्गत सर्व मार्ग
src/server/authz/routeGuard.ts मध्ये LOCAL_ONLY म्हणून वर्गीकृत केले आहेत. कोणत्याही प्रमाणीकरण शाखेपूर्वी
लूपबॅक तपासणी बिनशर्त चालते:
विनंती येते
→ isLocalOnlyPath(path)?
→ लूपबॅक नसल्यास → 403 LOCAL_ONLY (नेहमी, प्रमाणीकरण तपासणीपूर्वी)
→ लूपबॅक असल्यास → सामान्य प्रमाणीकरणाकडे पुढे जा
यामुळे लीक झालेल्या JWT मुळे (उदा., टनेलद्वारे) npm install किंवा
प्रक्रिया सुरू होण्यास प्रतिबंध होतो. संपूर्ण स्तर
मॅट्रिक्ससाठी docs/security/ROUTE_GUARD_TIERS.md पहा.
9Router आणि Mux यांना त्यांच्या स्वतःच्या HTTP एंडपॉइंटसाठी API की/बेअरर टोकन आवश्यक आहे. OmniRoute:
crypto.randomBytes(32).toString("base64url")द्वारे सेवा-विशिष्ट उपसर्गासह (nr_हा 9Router साठी,mx_हा Mux साठी) की निर्माण करते.- AES-256-GCM वापरून ती स्थिर संचयनात कूटबद्ध करते (प्रदाता क्रेडेन्शियल्ससाठी वापरलेले तेच सायफर).
- प्रक्रिया सुरू करताना ती डिक्रिप्ट करून पर्यावरण चल म्हणून अंतःक्षेपित करते —
9Router साठी
NINEROUTER_API_KEY, Mux साठीMUX_SERVER_AUTH_TOKEN(CLI फ्लॅग म्हणून कधीही नाही, त्यामुळे टोकनps/प्रक्रिया सूचीमध्ये कधीही दिसत नाही). - कोणत्याही HTTP प्रतिसादात साधा मजकूर असलेली की कधीही परत करत नाही.
CLIProxyAPI ला प्रक्रिया सुरू करताना अंतःक्षेपित केलेली समर्पित डेटा-प्लेन की मिळते
(needsApiKey: true — अॅडॅप्टरविरुद्ध मॉडेल समक्रमणासाठी वापरली जाते).
रिव्हर्स HTTP प्रॉक्सी (/dashboard/.../embed/[...path]) फक्त
http://127.0.0.1:{port} कडे अग्रेषित करण्यासाठी हार्डकोड केलेली आहे. ती लूपबॅक नसलेल्या
गंतव्यांकडे जाणाऱ्या पुनर्निर्देशनांचे कधीही अनुसरण करत नाही. लूपबॅक श्रेणीबाहेरील पत्त्यावर
रिझॉल्व्ह होणारी कोणतीही अपस्ट्रीम URL नाकारण्यासाठी ssrf-req-filter लायब्ररी वापरली जाते.
npm install हे execFile('npm', ['install', pkg, '--prefix', dir]) द्वारे चालवले जाते —
टेम्प्लेट लिटरल्स नाहीत, शेल नाही आणि बाह्य पथांचे कमांड स्ट्रिंगमध्ये इंटरपोलेशन नाही.
रनटाइम मूल्ये (पोर्ट्स, API की) चाइल्ड प्रक्रियेच्या env ऑब्जेक्टद्वारे दिली जातात.
/api/services/* कडून येणारे सर्व त्रुटी प्रतिसाद buildErrorBody() किंवा
sanitizeErrorMessage() मधून जातात. अपरिष्कृत err.stack आणि err.message कधीही
कॉलरला जसेच्या तसे परत केले जात नाहीत.
या 8 पायऱ्यांचे अनुसरण करा. अधिकृत संदर्भ म्हणून src/lib/services/installers/
आणि src/app/api/services/ मधील विद्यमान अंमलबजावण्या वाचा.
ninerouter.ts च्या धर्तीवर src/lib/services/installers/{name}.ts तयार करा:
export const NAME_PACKAGE = "your-npm-package";
export const NAME_DEFAULT_PORT = 20132; // मोकळा पोर्ट निवडा
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 मधील runNpm(['install', NAME_PACKAGE, '--prefix', dir]) वापरा
— execSync किंवा शेल इंटरपोलेशन कधीही वापरू नका.
src/lib/services/bootstrap.ts मधील SERVICES अॅरेमध्ये एक ServiceEntry जोडा:
{
tool: "myservice",
port: NAME_DEFAULT_PORT,
healthPath: "/health",
healthIntervalMs: 5_000,
stopTimeoutMs: 15_000,
logsBufferBytes: 5_242_880,
needsApiKey: true, // API की आवश्यक नसल्यास false
}cfg.tool === "myservice" हाताळण्यासाठी buildSpawnArgsFactory() विस्तारित करा.
src/lib/services/providerPlugins/ मध्ये असा ServiceProviderPlugin करार सादर केला आहे,
जो एकाच बॅकएंडची रचना दोन असंबंधित फाइल्समध्ये स्वतंत्रपणे व्यक्त करण्याऐवजी, बॅकएंडच्या
bootstrap.ts मधील ServiceEntry फील्ड्स आणि serviceBackends.ts मधील
मॅनिफेस्ट-टेम्प्लेट फील्ड्स एका ऑब्जेक्टमध्ये पॅकेज करतो. हे लिहिताना फक्त 9router
स्थलांतरित केले आहे — bootstrap.ts, getServiceProviderPlugin("9router")
(src/lib/services/providerPlugins/registry.ts) मधून त्याची SERVICES[] नोंद व्युत्पन्न करते;
प्लगइन कधीही अनुपस्थित असल्यास स्टार्टअप त्रुटी निर्माण होते. cliproxy, mux, आणि bifrost
यांमधील आधीपासून अस्तित्वात असलेले इनलाइन SERVICES[] लिटरल्स अपरिवर्तित राहतात.
open-sse/config/providerPluginManifest.ts मध्ये व्यवस्थित संरचित
ProviderPluginManifestEntry तयार करणारा अतिरिक्त
createServiceBackendManifestEntry(pluginId, template) हेल्परही जोडला गेला आहे, जो
SERVICE_BACKEND_MANIFEST_TEMPLATE नोंदीवरून ते तयार करतो — तो अद्याप कोणत्याही प्रत्यक्ष
विनंती मार्गाशी जोडलेला नाही (generateProviderPluginManifestFromRegistry() किंवा
/v1/providers/[provider]/models यांपैकी कोणत्याहीशी नाही); दुसऱ्या बॅकएंडसाठी करार
सिद्ध झाल्यानंतर हे पुढील काम म्हणून राहते.
समस्या #7333 अंतर्गत ट्रॅक केलेल्या पुढील PRs साठी पुढे ढकललेले काम: cliproxyapi चे
त्याच रजिस्ट्रीद्वारे स्थलांतर, mux/bifrost चे ServiceBackendPluginId युनियनमध्ये
सामान्यीकरण, एक्झिक्युटर-राउटिंगचे विशेष प्रकरण
(open-sse/executors/index.ts, open-sse/handlers/chatCore/executorProxy.ts) प्लगइन
करारामध्ये समाविष्ट करणे आणि createServiceBackendManifestEntry() ला प्रत्यक्ष
मॅनिफेस्ट/मॉडेल्स कोड मार्गाशी जोडणे.
src/lib/db/migrations/ मधील स्थलांतराद्वारे सेवेसाठी version_manager मध्ये एक पंक्ती
असल्याची खात्री करा. पंक्ती अशी असावी:
INSERT OR IGNORE INTO version_manager (tool, status, auto_start, provider_expose)
VALUES ('myservice', 'not_installed', 0, 0);src/app/api/services/{name}/ अंतर्गत:
_lib.ts getOrInitSupervisor() हेल्पर
install/route.ts POST — installer.install() कॉल करते
start/route.ts POST — supervisor.start() कॉल करते
stop/route.ts POST — supervisor.stop() कॉल करते
restart/route.ts POST — supervisor.restart() कॉल करते
update/route.ts POST — installer.update() कॉल करते
status/route.ts GET — प्रत्यक्ष + DB स्थिती विलीन करते
auto-start/route.ts POST — auto_start फ्लॅग टॉगल करते
सामायिक GET /api/services/[name]/logs रूट आधीच जोडलेला आहे — तेथे कोणतेही बदल
आवश्यक नाहीत.
सर्व त्रुटी प्रतिसाद createErrorResponse() / buildErrorBody() द्वारे हाताळा.
src/server/authz/routeGuard.ts मध्ये /api/services/ आधीच सूचीबद्ध असल्याची खात्री करा.
तुम्ही नवीन प्रीफिक्स सादर केल्यास (उदा., /api/tools/), ते
LOCAL_ONLY_API_PREFIXES आणि, जर ते प्रोसेसेस सुरू करत असेल, तर SPAWN_CAPABLE_PREFIXES
या दोन्हींमध्ये जोडा. tests/unit/authz/routeGuard.test.ts मध्ये चाचणी जोडा.
src/app/(dashboard)/dashboard/providers/services/tabs/{Name}ServiceTab.tsx तयार करा.
सामायिक कॉम्पोनंट्स पुन्हा वापरा:
ServiceStatusCard— थेट स्थिती + आरोग्य बॅजServiceLifecycleButtons— सुरू करा / थांबवा / रीस्टार्ट करा / अपडेट कराServiceLogsPanel— SSE लॉग टेल (/api/services/{name}/logsशी कनेक्ट होते)ApiKeyCard— की उघड करणे + बदलणे (needsApiKey: trueअसल्यास)
ServicesPageShell.tsx मध्ये टॅबची नोंदणी करा.
एम्बेडेड सेवा OpenAI-सुसंगत /v1/chat/completions एंडपॉइंट उपलब्ध करून देत असल्यास:
src/shared/constants/providers.tsमध्येisEmbeddedService: trueसह प्रोव्हायडर नोंद जोडा.BaseExecutorविस्तारित करणारीopen-sse/executors/{name}.tsतयार करा. प्रत्येक विनंतीसाठी पोर्ट आणि API की पुन्हा शोधा (कन्स्ट्रक्टरमध्ये कधीही कॅश करू नका). सुपरवायझरची स्थिती"running"नसताना503 service_not_runningप्रतिसाद परत करा.open-sse/config/providerRegistry.tsमध्ये सेवा प्रीफिक्ससह (उदा.,myservice/sub/model) मॉडेल्सची नोंदणी करा.modelSync.tsती अद्ययावत ठेवेल.
docs/frameworks/EMBEDDED-SERVICES.md(ही फाइल) अपडेट करा — §1 मधील तक्त्यात सेवा आणि §4 मध्ये कोणतेही नवीन एंडपॉइंट्स जोडा.tests/unit/services/मध्ये युनिट चाचण्या जोडा (लाइफसायकल, इंस्टॉलर, API संरचना).tests/integration/services/मध्ये इंटिग्रेशन चाचणी जोडा (RUN_SERVICES_INT=1च्या मागे).- नवीन एंडपॉइंट्ससह
docs/openapi.yamlअपडेट करा.
लक्षणे: Start बटण 503 प्रतिसाद देते, स्थिती "error" किंवा "starting" अशीच राहते.
तपासणीसूची:
GET /api/services/{name}/logsतपासा (किंवा डॅशबोर्डमधील Logs पॅनेल).Error: ENOENT,address already in use, किंवाCannot find moduleयांसारख्या ओळी शोधा.npmPATH मध्ये असल्याची खात्री करा: OmniRoute चालवणाऱ्या त्याच वापरकर्ता खात्यातूनwhich npmचालवा.- सेवा इंस्टॉल केलेली असल्याची खात्री करा:
installedVersionसाठीGET /api/services/{name}/statusतपासा. तेnullअसल्यास, प्रथम इंस्टॉलेशन चालवा. DATA_DIR/services/{name}/node_modules/अस्तित्वात आहे आणि रिकामी नाही याची खात्री करा.- निर्गमनाचे शुद्धीकृत कारण पाहण्यासाठी स्थिती प्रतिसादातील
lastErrorफील्ड तपासा.
लक्षणे: "running" किंवा "error" स्थितीत जाण्यापूर्वी स्थिती बराच वेळ "starting" अशीच राहते.
स्पष्टीकरण: 9Router च्या कोल्ड स्टार्टमध्ये मोठे अवलंबित्व-वृक्ष (DNS, टनेल, MITM मॉड्यूल्स) इम्पोर्ट करणे समाविष्ट असते. डीफॉल्ट आरोग्य-तपासणी अंतर 2 s आहे आणि पर्यवेक्षक टाइमआउट घोषित करण्यापूर्वी 3 प्रयत्न करतो (परंतु पोलिंग सुरू ठेवतो).
उपाय: healthIntervalMs आणि waitForHealthy टाइमआउट (healthIntervalMs * 3) हे bootstrap.ts मध्ये कॉन्फिगर करता येतात. सुरू होण्यासाठी अधिक वेळ लागणाऱ्या सेवांसाठी healthIntervalMs चे मूल्य 5000 आणि stopTimeoutMs चे मूल्य 30 000 करा.
लक्षणे: लॉगमध्ये address already in use :::20130 दिसते.
कारणे:
- दुसरी एखादी प्रोसेस आधीपासून पोर्ट 20130 वापरत आहे.
- मागील 9Router प्रोसेस पूर्णपणे थांबवली गेली नाही (झॉम्बी PID).
उपाय:
.envमधीलNINEROUTER_PORTपर्यावरणीय चलाद्वारे डीफॉल्ट पोर्ट बदला.- संघर्ष करणारी प्रोसेस शोधून बंद करा:
lsof -ti :20130 | xargs kill -9. bootstrap.tsमधीलportफील्डद्वारे प्रत्येक सेवेसाठी स्वतंत्रपणे पोर्ट कॉन्फिगर करता येतो.
टीप: OmniRoute च्या डीफॉल्ट पोर्ट 20128 सोबत संघर्ष टाळण्यासाठी 9Router विशेषतः पोर्ट 20130 डीफॉल्ट म्हणून वापरतो.
लक्षणे: इंस्टॉलेशन 500 प्रतिसाद देते, लॉगमध्ये EACCES किंवा permission denied दिसते.
कारणे:
- OmniRoute प्रोसेसला
DATA_DIRकिंवा तिच्या मूळ निर्देशिकेत लिहिण्याची परवानगी नाही. - मॅप केलेल्या व्हॉल्यूमवर लेखन-अधिकार नसताना रूटलेस Docker मध्ये चालवले जात आहे.
उपाय:
DATA_DIRतपासा (डीफॉल्ट:~/.omniroute/):ls -la ~/.omniroute/- OmniRoute प्रोसेसच्या वापरकर्त्याच्या मालकीची ही निर्देशिका असल्याची खात्री करा:
chown -R $USER ~/.omniroute/ - Docker मध्ये, व्हॉल्यूम माउंटला कंटेनर वापरकर्त्यासाठी योग्य परवानग्या असल्याची खात्री करा.
लक्षणे: अपडेट InstallError सह 500 प्रतिसाद देते, लॉगमध्ये नेटवर्क टाइमआउट दिसतो.
तपासणीसूची:
- npm रजिस्ट्रीशी संपर्क साधता येत असल्याची खात्री करा:
npm ping. - कॉर्पोरेट प्रॉक्सी तपासा:
npm config get proxy,npm config get https-proxy. - इंस्टॉलेशन स्वहस्ते करून पाहा:
npm install {package}@latest --prefix ~/.omniroute/services/{name}/. - एअर-गॅपच्या मागे असल्यास, टारबॉल आधीच डाउनलोड करा आणि
npm install /path/to/tarball.tgzवापरा.
लक्षणे: स्थिती 5 सेकंदांपेक्षा कमी वेळात "starting" वरून "error" मध्ये बदलते. lastError मध्ये "Fast crash (exited with code 1)" दिसते.
तपासणीसूची:
- लॉगचा संपूर्ण शेवटचा भाग वाचा:
GET /api/services/{name}/logs?tail=500. - सामान्य कारण: सेवेला अपेक्षित असलेली पर्यावरणीय चले उपलब्ध नसणे.
- 9Router साठी: स्पॉन करताना पास केलेल्या env मध्ये
NINEROUTER_DISABLE_MITM=trueआणिNINEROUTER_DISABLE_TUNNEL=trueअसल्याची खात्री करा (installers/ninerouter.tsमधीलresolveSpawnArgsपाहा).
प्रश्न: एम्बेडेड सेवांचे endpoints मी non-loopback clients साठी उघड करू शकतो का?
नाही. LOCAL_ONLY tier हेतुपुरस्सर ठेवलेला आहे (अपरिवर्तनीय नियम #17). npm install चालवू शकणारे किंवा node processes सुरू करू शकणारे routes non-loopback traffic मधून उपलब्ध असता कामा नयेत, कारण tunnel (Cloudflare, Ngrok, Tailscale) द्वारे JWT लीक झाल्यास अन्यथा कोणतेही processes सुरू करणे शक्य होईल. /api/services/ साठी यामधून वगळण्याची कोणतीही तरतूद नाही — /api/mcp/ च्या विपरीत, ते manage-scope bypass यादीतून वगळलेले आहे. docs/security/ROUTE_GUARD_TIERS.md पहा.
प्रश्न: production/cloud deployments मध्ये 9Router आणि CLIProxyAPI उपलब्ध असतील का?
होय. दोन्ही सेवा OmniRoute प्रमाणेच local-first मॉडेलचे अनुसरण करतात. त्या त्याच मशीनवर चालतात आणि loopback द्वारे परस्परांशी संवाद साधतात. येथे "Production" म्हणजे OmniRoute deploy केलेला VPS किंवा local server; remote cloud provider नव्हे.
प्रश्न: supervisor debug कसा करावा?
- SSE log stream चे tail करा:
curl -N http://localhost:20128/api/services/9router/logs. - OmniRoute च्या pino output मधील
service:supervisornamespace नुसार filter केलेले structured logs तपासा. - DB row तपासा:
sqlite3 ~/.omniroute/omniroute.db "SELECT * FROM version_manager WHERE tool='9router'". - सध्याची live state, PID, health आणि
lastErrorएकाच call मध्ये पाहण्यासाठीGET /api/services/9router/statusवापरा.
प्रश्न: supervisor मध्ये health: "degraded" किंवा health: "unknown" दिसते, पण state "running" आहे. ही समस्या आहे का?
"degraded" म्हणजे health probe ने non-200 response परत केला. "unknown" म्हणजे अद्याप कोणताही probe पूर्ण झालेला नाही (पहिल्या poll सोबत race). startup दरम्यान या दोन्ही स्थिती तात्पुरत्या असतात. "running" झाल्यानंतर healthIntervalMs * 3 ms पेक्षा जास्त काळ health "degraded" राहिल्यास, embedded service चालू आहे, पण तिचे HTTP API प्रतिसाद देत नाही. status response मधील port योग्य आहे का आणि सेवा प्रत्यक्षात त्या port वर listen करत आहे का ते तपासा.
प्रश्न: पूर्ण restart न करता मी 9Router API key बदलू शकतो का?
नाही. spawn वेळी API key ही environment variable द्वारे 9Router ला दिली जाते. चालू process मधील environment variables बदलता येत नाहीत. नवीन key लागू करण्यासाठी POST .../rotate-key सेवा आपोआप थांबवते आणि पुन्हा सुरू करते. key rotation सेवेच्या stopTimeoutMs (default 15 s) आणि तिच्या startup वेळेच्या एकत्रित कालावधीत प्रभावी होते.
प्रश्न: ring buffer ची मर्यादा किती आहे आणि तो भरल्यावर काय होते?
प्रत्येक सेवेसाठी स्वतंत्र 5 MB ring buffer असतो. buffer भरल्यावर नवीन lines साठी जागा करण्यासाठी सर्वांत जुन्या log lines काढून टाकल्या जातात. SSE snapshot event हा tail मर्यादेतील सर्वांत अलीकडील lines परत करतो. DB row मध्ये logsBufferPath सेट केलेले नसल्यास logs disk वर कायमस्वरूपी जतन केले जात नाहीत.
docs/security/ROUTE_GUARD_TIERS.md— LOCAL_ONLY tier चे तपशीलdocs/architecture/CODEBASE_DOCUMENTATION.md— §3.2 Embedded Services module mappingdocs/architecture/ARCHITECTURE.md— system-level संदर्भdocs/openapi.yaml— machine-readable endpoint व्याख्याCLAUDE.md§"Adding a New Embedded Service" — झटपट-संदर्भ checklist