Skip to content

Latest commit

 

History

History
901 lines (663 loc) · 76.6 KB

EMBEDDED-SERVICES.md

File metadata and controls

901 lines (663 loc) · 76.6 KB

Embedded Services (मराठी)

🌐 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 असलेल्या त्याच मशीनवर चालतात आणि लूपबॅकद्वारे संवाद साधतात.


अनुक्रमणिका

  1. आढावा
  2. आर्किटेक्चर — 4 स्तर
  3. लाइफसायकल स्थिती यंत्र
  4. API संदर्भ
  5. सुरक्षा
  6. नवीन एम्बेडेड सेवा जोडणे
  7. समस्यानिवारण
  8. वारंवार विचारले जाणारे प्रश्न

1. आढावा

एम्बेडेड सेवा का?

सहा सेवा एम्बेड केलेल्या आहेत:

सेवा 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 (तीन टॅब)
स्वयंचलित प्रारंभ प्रत्येक सेवेसाठी टॉगल, डीफॉल्टनुसार बंद

2. आर्किटेक्चर — 4 स्तर

┌────────────────────────────────────────────────────────────────────┐
│  स्तर 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)

3. लाइफसायकल स्थिती यंत्र

                    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 बटण एकाच वेळी सक्रिय झाल्यास यामुळे रेस कंडिशन्स टाळल्या जातात.


4. API संदर्भ

/api/services/ अंतर्गत असलेले सर्व मार्ग LOCAL_ONLY आहेत (केवळ loopback, कठोर नियम #17). auth token कोणताही असला तरी non-loopback विनंत्यांना 403 LOCAL_ONLY मिळतो.

4.1 9Router endpoints (11 मार्ग)

POST /api/services/9router/install

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 त्रुटी अनुकूल संदेशांच्या स्वरूपात दाखवल्या जातात.


POST /api/services/9router/start

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
}

POST /api/services/9router/stop

9Router व्यवस्थितपणे थांबवते. SIGTERM पाठवते, 15 s प्रतीक्षा करते आणि तरीही चालू असल्यास SIGKILL पाठवते. आधीच थांबलेले असताना idempotent असते.

विनंतीचे body: नाही

प्रतिसाद:

स्थिती वर्णन
200 ServiceStatus (state: "stopped")
503 थांबवणे अनपेक्षितपणे अयशस्वी झाले

POST /api/services/9router/restart

operation lock अंतर्गत stop() आणि त्यानंतर start() करण्याच्या समतुल्य.

विनंतीचे body: नाही

प्रतिसाद: start प्रमाणेच (अंतिम ServiceStatus परत करते).


POST /api/services/9router/update

9Router अधिक नवीन npm version वर update करते. service चालू असल्यास, प्रथम ती थांबवली जाते, npm install चालवले जाते (नवीन version त्याच ठिकाणी स्थापित करून) आणि त्यानंतर service पुन्हा सुरू केली जाते.

विनंतीचे body (सर्व पर्यायी):

{ "version": "latest" }

प्रतिसाद:

स्थिती वर्णन
200 { ok: true, previousVersion: "...", installedVersion: "..." }
400 अवैध body
500 npm update अयशस्वी

POST /api/services/9router/rotate-key

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) स्वरूपात संग्रहित केला जातो.


GET /api/services/9router/status

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
}

POST /api/services/9router/auto-start

auto-start flag toggle करते. enabled: true असताना, पुढील वेळी OmniRoute boot झाल्यावर service आपोआप सुरू होते (service स्थापित केलेली असल्यास).

विनंतीचे body:

{ "enabled": true }

प्रतिसाद:

स्थिती वर्णन
200 { autoStart: true }
400 अवैध body

GET /api/services/9router/logs

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 नोंदणीकृत नाही)

4.2 CLIProxyAPI एंडपॉइंट्स (10 मार्ग)

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] डायनॅमिक सेगमेंट वापरून सर्व चार सेवांसाठी कार्य करतो.


4.3 Mux एंडपॉइंट्स (8 मार्ग)

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 स्वयंचलित प्रारंभ टॉगल करा

4.4 Bifrost एंडपॉइंट्स (8 मार्ग)

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 ला नेहमी प्राधान्य दिले जाते.


4.5 Dario एंडपॉइंट्स (12 मार्ग)

इतर सेवांसारखीच 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 च्या संरक्षणाखाली).

4.6 open-wa एंडपॉइंट्स (7 मार्ग)

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-प्रतिमा एंडपॉइंट नाही.


4.7 रिव्हर्स प्रॉक्सी (9Router डॅशबोर्ड एम्बेड)

डॅशबोर्ड अंतर्गत रिव्हर्स प्रॉक्सीद्वारे 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 मिळवणारा हल्लेखोर एम्बेड केलेल्या सेवांमध्ये प्रॉक्सी करू शकत नाही.


5. सुरक्षा

LOCAL_ONLY अंमलबजावणी (कठोर नियम #17)

/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 पहा.

API की अंतःक्षेपण

9Router आणि Mux यांना त्यांच्या स्वतःच्या HTTP एंडपॉइंटसाठी API की/बेअरर टोकन आवश्यक आहे. OmniRoute:

  1. crypto.randomBytes(32).toString("base64url") द्वारे सेवा-विशिष्ट उपसर्गासह (nr_ हा 9Router साठी, mx_ हा Mux साठी) की निर्माण करते.
  2. AES-256-GCM वापरून ती स्थिर संचयनात कूटबद्ध करते (प्रदाता क्रेडेन्शियल्ससाठी वापरलेले तेच सायफर).
  3. प्रक्रिया सुरू करताना ती डिक्रिप्ट करून पर्यावरण चल म्हणून अंतःक्षेपित करते — 9Router साठी NINEROUTER_API_KEY, Mux साठी MUX_SERVER_AUTH_TOKEN (CLI फ्लॅग म्हणून कधीही नाही, त्यामुळे टोकन ps/प्रक्रिया सूचीमध्ये कधीही दिसत नाही).
  4. कोणत्याही HTTP प्रतिसादात साधा मजकूर असलेली की कधीही परत करत नाही.

CLIProxyAPI ला प्रक्रिया सुरू करताना अंतःक्षेपित केलेली समर्पित डेटा-प्लेन की मिळते (needsApiKey: true — अॅडॅप्टरविरुद्ध मॉडेल समक्रमणासाठी वापरली जाते).

SSRF संरक्षण

रिव्हर्स HTTP प्रॉक्सी (/dashboard/.../embed/[...path]) फक्त http://127.0.0.1:{port} कडे अग्रेषित करण्यासाठी हार्डकोड केलेली आहे. ती लूपबॅक नसलेल्या गंतव्यांकडे जाणाऱ्या पुनर्निर्देशनांचे कधीही अनुसरण करत नाही. लूपबॅक श्रेणीबाहेरील पत्त्यावर रिझॉल्व्ह होणारी कोणतीही अपस्ट्रीम URL नाकारण्यासाठी ssrf-req-filter लायब्ररी वापरली जाते.

शेल सुरक्षा (कठोर नियम #13)

npm install हे execFile('npm', ['install', pkg, '--prefix', dir]) द्वारे चालवले जाते — टेम्प्लेट लिटरल्स नाहीत, शेल नाही आणि बाह्य पथांचे कमांड स्ट्रिंगमध्ये इंटरपोलेशन नाही. रनटाइम मूल्ये (पोर्ट्स, API की) चाइल्ड प्रक्रियेच्या env ऑब्जेक्टद्वारे दिली जातात.

त्रुटी निर्जंतुकीकरण (कठोर नियम #12)

/api/services/* कडून येणारे सर्व त्रुटी प्रतिसाद buildErrorBody() किंवा sanitizeErrorMessage() मधून जातात. अपरिष्कृत err.stack आणि err.message कधीही कॉलरला जसेच्या तसे परत केले जात नाहीत.


6. नवीन एम्बेडेड सेवा जोडणे

या 8 पायऱ्यांचे अनुसरण करा. अधिकृत संदर्भ म्हणून src/lib/services/installers/ आणि src/app/api/services/ मधील विद्यमान अंमलबजावण्या वाचा.

पायरी 1 — इंस्टॉलर तयार करा

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 किंवा शेल इंटरपोलेशन कधीही वापरू नका.

पायरी 2 — बूटस्ट्रॅपमध्ये नोंदणी करा

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() विस्तारित करा.

प्लग करता येणारा प्रदाता-प्लगइन करार (टप्पा 1, #7333)

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() ला प्रत्यक्ष मॅनिफेस्ट/मॉडेल्स कोड मार्गाशी जोडणे.

पायरी 3 — स्थलांतर आणि DB सीड जोडा

src/lib/db/migrations/ मधील स्थलांतराद्वारे सेवेसाठी version_manager मध्ये एक पंक्ती असल्याची खात्री करा. पंक्ती अशी असावी:

INSERT OR IGNORE INTO version_manager (tool, status, auto_start, provider_expose)
VALUES ('myservice', 'not_installed', 0, 0);

पायरी 4 — 7 API एंडपॉइंट तयार करा

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() द्वारे हाताळा.

पायरी 5 — LOCAL_ONLY_API_PREFIXES मध्ये जोडा

src/server/authz/routeGuard.ts मध्ये /api/services/ आधीच सूचीबद्ध असल्याची खात्री करा. तुम्ही नवीन प्रीफिक्स सादर केल्यास (उदा., /api/tools/), ते LOCAL_ONLY_API_PREFIXES आणि, जर ते प्रोसेसेस सुरू करत असेल, तर SPAWN_CAPABLE_PREFIXES या दोन्हींमध्ये जोडा. tests/unit/authz/routeGuard.test.ts मध्ये चाचणी जोडा.

पायरी 6 — UI टॅब जोडा

src/app/(dashboard)/dashboard/providers/services/tabs/{Name}ServiceTab.tsx तयार करा. सामायिक कॉम्पोनंट्स पुन्हा वापरा:

  • ServiceStatusCard — थेट स्थिती + आरोग्य बॅज
  • ServiceLifecycleButtons — सुरू करा / थांबवा / रीस्टार्ट करा / अपडेट करा
  • ServiceLogsPanel — SSE लॉग टेल (/api/services/{name}/logs शी कनेक्ट होते)
  • ApiKeyCard — की उघड करणे + बदलणे (needsApiKey: true असल्यास)

ServicesPageShell.tsx मध्ये टॅबची नोंदणी करा.

पायरी 7 — प्रोव्हायडर नोंद जोडा (जर सेवा रूटिंग लक्ष्य असेल)

एम्बेडेड सेवा OpenAI-सुसंगत /v1/chat/completions एंडपॉइंट उपलब्ध करून देत असल्यास:

  1. src/shared/constants/providers.ts मध्ये isEmbeddedService: true सह प्रोव्हायडर नोंद जोडा.
  2. BaseExecutor विस्तारित करणारी open-sse/executors/{name}.ts तयार करा. प्रत्येक विनंतीसाठी पोर्ट आणि API की पुन्हा शोधा (कन्स्ट्रक्टरमध्ये कधीही कॅश करू नका). सुपरवायझरची स्थिती "running" नसताना 503 service_not_running प्रतिसाद परत करा.
  3. open-sse/config/providerRegistry.ts मध्ये सेवा प्रीफिक्ससह (उदा., myservice/sub/model) मॉडेल्सची नोंदणी करा. modelSync.ts ती अद्ययावत ठेवेल.

पायरी 8 — दस्तऐवजीकरण आणि चाचणी

  1. docs/frameworks/EMBEDDED-SERVICES.md (ही फाइल) अपडेट करा — §1 मधील तक्त्यात सेवा आणि §4 मध्ये कोणतेही नवीन एंडपॉइंट्स जोडा.
  2. tests/unit/services/ मध्ये युनिट चाचण्या जोडा (लाइफसायकल, इंस्टॉलर, API संरचना).
  3. tests/integration/services/ मध्ये इंटिग्रेशन चाचणी जोडा (RUN_SERVICES_INT=1 च्या मागे).
  4. नवीन एंडपॉइंट्ससह docs/openapi.yaml अपडेट करा.

7. समस्यानिवारण

सेवा सुरू होत नाही

लक्षणे: Start बटण 503 प्रतिसाद देते, स्थिती "error" किंवा "starting" अशीच राहते.

तपासणीसूची:

  1. GET /api/services/{name}/logs तपासा (किंवा डॅशबोर्डमधील Logs पॅनेल). Error: ENOENT, address already in use, किंवा Cannot find module यांसारख्या ओळी शोधा.
  2. npm PATH मध्ये असल्याची खात्री करा: OmniRoute चालवणाऱ्या त्याच वापरकर्ता खात्यातून which npm चालवा.
  3. सेवा इंस्टॉल केलेली असल्याची खात्री करा: installedVersion साठी GET /api/services/{name}/status तपासा. ते null असल्यास, प्रथम इंस्टॉलेशन चालवा.
  4. DATA_DIR/services/{name}/node_modules/ अस्तित्वात आहे आणि रिकामी नाही याची खात्री करा.
  5. निर्गमनाचे शुद्धीकृत कारण पाहण्यासाठी स्थिती प्रतिसादातील lastError फील्ड तपासा.

कोल्ड स्टार्ट मंद आहे (running स्थिती गाठण्यासाठी > 10 s)

लक्षणे: "running" किंवा "error" स्थितीत जाण्यापूर्वी स्थिती बराच वेळ "starting" अशीच राहते.

स्पष्टीकरण: 9Router च्या कोल्ड स्टार्टमध्ये मोठे अवलंबित्व-वृक्ष (DNS, टनेल, MITM मॉड्यूल्स) इम्पोर्ट करणे समाविष्ट असते. डीफॉल्ट आरोग्य-तपासणी अंतर 2 s आहे आणि पर्यवेक्षक टाइमआउट घोषित करण्यापूर्वी 3 प्रयत्न करतो (परंतु पोलिंग सुरू ठेवतो).

उपाय: healthIntervalMs आणि waitForHealthy टाइमआउट (healthIntervalMs * 3) हे bootstrap.ts मध्ये कॉन्फिगर करता येतात. सुरू होण्यासाठी अधिक वेळ लागणाऱ्या सेवांसाठी healthIntervalMs चे मूल्य 5000 आणि stopTimeoutMs चे मूल्य 30 000 करा.


पोर्ट संघर्ष (EADDRINUSE)

लक्षणे: लॉगमध्ये address already in use :::20130 दिसते.

कारणे:

  • दुसरी एखादी प्रोसेस आधीपासून पोर्ट 20130 वापरत आहे.
  • मागील 9Router प्रोसेस पूर्णपणे थांबवली गेली नाही (झॉम्बी PID).

उपाय:

  1. .env मधील NINEROUTER_PORT पर्यावरणीय चलाद्वारे डीफॉल्ट पोर्ट बदला.
  2. संघर्ष करणारी प्रोसेस शोधून बंद करा: lsof -ti :20130 | xargs kill -9.
  3. bootstrap.ts मधील port फील्डद्वारे प्रत्येक सेवेसाठी स्वतंत्रपणे पोर्ट कॉन्फिगर करता येतो.

टीप: OmniRoute च्या डीफॉल्ट पोर्ट 20128 सोबत संघर्ष टाळण्यासाठी 9Router विशेषतः पोर्ट 20130 डीफॉल्ट म्हणून वापरतो.


इंस्टॉलेशनदरम्यान परवानगी नाकारली (EACCES)

लक्षणे: इंस्टॉलेशन 500 प्रतिसाद देते, लॉगमध्ये EACCES किंवा permission denied दिसते.

कारणे:

  • OmniRoute प्रोसेसला DATA_DIR किंवा तिच्या मूळ निर्देशिकेत लिहिण्याची परवानगी नाही.
  • मॅप केलेल्या व्हॉल्यूमवर लेखन-अधिकार नसताना रूटलेस Docker मध्ये चालवले जात आहे.

उपाय:

  1. DATA_DIR तपासा (डीफॉल्ट: ~/.omniroute/): ls -la ~/.omniroute/
  2. OmniRoute प्रोसेसच्या वापरकर्त्याच्या मालकीची ही निर्देशिका असल्याची खात्री करा: chown -R $USER ~/.omniroute/
  3. Docker मध्ये, व्हॉल्यूम माउंटला कंटेनर वापरकर्त्यासाठी योग्य परवानग्या असल्याची खात्री करा.

अपडेट अयशस्वी होते (npm install टाइमआउट किंवा नेटवर्क त्रुटी)

लक्षणे: अपडेट InstallError सह 500 प्रतिसाद देते, लॉगमध्ये नेटवर्क टाइमआउट दिसतो.

तपासणीसूची:

  1. npm रजिस्ट्रीशी संपर्क साधता येत असल्याची खात्री करा: npm ping.
  2. कॉर्पोरेट प्रॉक्सी तपासा: npm config get proxy, npm config get https-proxy.
  3. इंस्टॉलेशन स्वहस्ते करून पाहा: npm install {package}@latest --prefix ~/.omniroute/services/{name}/.
  4. एअर-गॅपच्या मागे असल्यास, टारबॉल आधीच डाउनलोड करा आणि npm install /path/to/tarball.tgz वापरा.

सुरू केल्यानंतर सेवा लगेच "error" स्थिती दर्शवते (जलद क्रॅश)

लक्षणे: स्थिती 5 सेकंदांपेक्षा कमी वेळात "starting" वरून "error" मध्ये बदलते. lastError मध्ये "Fast crash (exited with code 1)" दिसते.

तपासणीसूची:

  1. लॉगचा संपूर्ण शेवटचा भाग वाचा: GET /api/services/{name}/logs?tail=500.
  2. सामान्य कारण: सेवेला अपेक्षित असलेली पर्यावरणीय चले उपलब्ध नसणे.
  3. 9Router साठी: स्पॉन करताना पास केलेल्या env मध्ये NINEROUTER_DISABLE_MITM=true आणि NINEROUTER_DISABLE_TUNNEL=true असल्याची खात्री करा (installers/ninerouter.ts मधील resolveSpawnArgs पाहा).

8. वारंवार विचारले जाणारे प्रश्न

प्रश्न: एम्बेडेड सेवांचे 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 कसा करावा?

  1. SSE log stream चे tail करा: curl -N http://localhost:20128/api/services/9router/logs.
  2. OmniRoute च्या pino output मधील service:supervisor namespace नुसार filter केलेले structured logs तपासा.
  3. DB row तपासा: sqlite3 ~/.omniroute/omniroute.db "SELECT * FROM version_manager WHERE tool='9router'".
  4. सध्याची 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 mapping
  • docs/architecture/ARCHITECTURE.md — system-level संदर्भ
  • docs/openapi.yaml — machine-readable endpoint व्याख्या
  • CLAUDE.md §"Adding a New Embedded Service" — झटपट-संदर्भ checklist