Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host. Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean. Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
44 KiB
CLAUDE.md (हिन्दी)
🌐 Languages: 🇺🇸 English · 🇸🇦 ar · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇪🇸 es · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇳 gu · 🇮🇱 he · 🇭🇺 hu · 🇮🇩 id · 🇮🇩 in · 🇮🇹 it · 🇯🇵 ja · 🇰🇷 ko · 🇮🇳 mr · 🇲🇾 ms · 🇳🇱 nl · 🇳🇴 no · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇸🇰 sk · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇻🇳 vi · 🇨🇳 zh-CN
इस फ़ाइल में इस रिपॉजिटरी में कोड के साथ काम करते समय Claude Code (claude.ai/code) के लिए मार्गदर्शन प्रदान किया गया है।
त्वरित प्रारंभ
npm install # निर्भरता स्थापित करें (auto-generates .env from .env.example)
npm run dev # http://localhost:20128 पर विकास सर्वर
npm run build # उत्पादन निर्माण (Next.js 16 standalone)
npm run lint # ESLint (0 त्रुटियाँ अपेक्षित; चेतावनियाँ पूर्व-निर्धारित हैं)
npm run typecheck:core # TypeScript जांच (स्वच्छ होनी चाहिए)
npm run typecheck:noimplicit:core # सख्त जांच (कोई निहित कोई नहीं)
npm run test:coverage # यूनिट परीक्षण + कवरेज गेट (75/75/75/70 — कथन/लाइन/कार्य/शाखाएँ)
npm run check # lint + परीक्षण संयुक्त
npm run check:cycles # वृत्ताकार निर्भरताएँ पहचानें
परीक्षण चलाना
# एकल परीक्षण फ़ाइल (Node.js मूल परीक्षण रनर — अधिकांश परीक्षण)
node --import tsx/esm --test tests/unit/your-file.test.ts
# Vitest (MCP सर्वर, autoCombo, कैश)
npm run test:vitest
# सभी सूट
npm run test:all
पूर्ण परीक्षण मैट्रिक्स के लिए, CONTRIBUTING.md → "परीक्षण चलाना" देखें। गहन आर्किटेक्चर के लिए, AGENTS.md देखें।
परियोजना एक नज़र में
OmniRoute — एकीकृत AI प्रॉक्सी/राउटर। एक एंडपॉइंट, 329 LLM प्रदाता, स्वचालित फॉलबैक।
| परत | स्थान | उद्देश्य |
|---|---|---|
| API रूट्स | src/app/api/v1/ |
Next.js ऐप राउटर — प्रवेश बिंदु |
| हैंडलर्स | open-sse/handlers/ |
अनुरोध प्रसंस्करण (चैट, एम्बेडिंग, आदि) |
| निष्पादक | open-sse/executors/ |
प्रदाता-विशिष्ट HTTP डिस्पैच |
| अनुवादक | open-sse/translator/ |
प्रारूप रूपांतरण (OpenAI↔Claude↔Gemini) |
| ट्रांसफार्मर | open-sse/transformer/ |
प्रतिक्रियाएँ API ↔ चैट पूर्णता |
| सेवाएँ | open-sse/services/ |
कॉम्बो राउटिंग, दर सीमाएँ, कैशिंग, आदि |
| डेटाबेस | src/lib/db/ |
110 top-level SQLite domain modules, 130 migrations |
| डोमेन/नीति | src/domain/ |
नीति इंजन, लागत नियम, फॉलबैक लॉजिक |
| MCP सर्वर | open-sse/mcp-server/ |
107 unique tools, 3 transports (stdio / SSE / Streamable HTTP), 32 scopes |
| A2A सर्वर | src/lib/a2a/ |
JSON-RPC 2.0 एजेंट प्रोटोकॉल |
| कौशल | src/lib/skills/ |
विस्तारित कौशल ढांचा |
| मेमोरी | src/lib/memory/ |
स्थायी संवादात्मक मेमोरी |
मोनोरेपो: src/ (Next.js 16 ऐप), open-sse/ (स्ट्रीमिंग इंजन कार्यक्षेत्र), electron/ (डेस्कटॉप ऐप), tests/, bin/ (CLI प्रवेश बिंदु)।
अनुरोध पाइपलाइन
Client → /v1/chat/completions (Next.js route)
→ CORS → Zod validation → auth? → policy check → prompt injection guard
→ handleChatCore() [open-sse/handlers/chatCore.ts]
→ cache check → rate limit → combo routing?
→ resolveComboTargets() → handleSingleModel() per target
→ translateRequest() → getExecutor() → executor.execute()
→ fetch() upstream → retry w/ backoff
→ response translation → SSE stream or JSON
→ If Responses API: responsesTransformer.ts TransformStream
API रूट एक सुसंगत पैटर्न का पालन करते हैं: Route → CORS preflight → Zod body validation → Optional auth (extractApiKey/isValidApiKey) → API key policy enforcement → Handler delegation (open-sse)। कोई वैश्विक Next.js मिडलवेयर नहीं — इंटरसेप्शन रूट-विशिष्ट है।
Combo routing (open-sse/services/combo.ts): 19 public strategies (priority, weighted, fill-first, round-robin, p2c, random, least-used, cost-optimized, reset-aware, reset-window, headroom, strict-random, auto, lkgp, context-optimized, cache-optimized, context-relay, fusion, pipeline). Each target calls handleSingleModel(), which wraps handleChatCore() with per-target error handling and circuit-breaker checks. See docs/routing/AUTO-COMBO.md for the 13-factor Auto-Combo scoring and docs/architecture/RESILIENCE_GUIDE.md for the 3 resilience layers.
लचीलापन रनटाइम स्थिति
OmniRoute में तीन संबंधित लेकिन अलग अस्थायी-फेल्योर तंत्र हैं। रूटिंग व्यवहार को डिबग करते समय उनके दायरे को अलग रखें। एक झलक के लिए 3-लेयर लचीलापन आरेख देखें (स्रोत: docs/diagrams/resilience-3layers.mmd)।
प्रदाता सर्किट ब्रेकर
दायरा: पूरा प्रदाता, जैसे glm, openai, anthropic।
उद्देश्य: एक प्रदाता को ट्रैफ़िक भेजना बंद करें जो लगातार अपस्ट्रीम/सेवा स्तर पर विफल हो रहा है, ताकि एक अस्वस्थ प्रदाता हर अनुरोध को धीमा न करे।
कार्यान्वयन:
- कोर क्लास:
src/shared/utils/circuitBreaker.ts - चैट गेट/एक्ज़ीक्यूशन वायरिंग:
src/sse/handlers/chatHelpers.ts,src/sse/handlers/chat.ts - रनटाइम स्थिति API:
src/app/api/monitoring/health/route.ts - साझा रैपर:
open-sse/services/accountFallback.ts - स्थायी स्थिति तालिका:
domain_circuit_breakers
राज्य:
CLOSED: सामान्य ट्रैफ़िक की अनुमति है।OPEN: प्रदाता अस्थायी रूप से अवरुद्ध है; कॉलर्स को प्रदाता-सर्किट-खुला प्रतिक्रिया मिलती है या कॉम्बो रूटिंग किसी अन्य लक्ष्य पर कूद जाती है।HALF_OPEN: रीसेट टाइमआउट समाप्त हो गया है; एक प्रॉब अनुरोध की अनुमति दें। सफलता ब्रेकर को बंद कर देती है, विफलता इसे फिर से खोल देती है।
डिफ़ॉल्ट (open-sse/config/constants.ts):
- OAuth प्रदाता: थ्रेशोल्ड
3, रीसेट टाइमआउट60s। - API-key प्रदाता: थ्रेशोल्ड
5, रीसेट टाइमआउट30s। - स्थानीय प्रदाता: थ्रेशोल्ड
2, रीसेट टाइमआउट15s।
केवल प्रदाता-स्तरीय विफलता स्थिति को प्रदाता ब्रेकर को ट्रिप करना चाहिए:
(408, 500, 502, 503, 504);
सामान्य खाता/की/मॉडल त्रुटियों जैसे अधिकांश 401, 403, या 429 मामलों के लिए पूरे प्रदाता ब्रेकर को ट्रिप न करें। वे आमतौर पर कनेक्शन कूलडाउन या मॉडल लॉकआउट से संबंधित होते हैं। एक सामान्य API-key प्रदाता 403 को पुनर्प्राप्त किया जाना चाहिए जब तक कि इसे एक टर्मिनल प्रदाता/खाता त्रुटि के रूप में वर्गीकृत नहीं किया गया हो।
ब्रेकर आलसी पुनर्प्राप्ति का उपयोग करता है, बैकग्राउंड टाइमर नहीं। जब OPEN समाप्त होता है, तो getStatus(), canExecute(), और getRetryAfterMs() जैसे रीड्स स्थिति को HALF_OPEN में ताज़ा करते हैं, ताकि डैशबोर्ड और कॉम्बो उम्मीदवार बिल्डर एक समाप्त प्रदाता को हमेशा के लिए बाहर न रखें।
कनेक्शन कूलडाउन
दायरा: एक प्रदाता कनेक्शन/खाता/की।
उद्देश्य: एक खराब कुंजी/खाते को अस्थायी रूप से छोड़ना जबकि उसी प्रदाता के लिए अन्य कनेक्शन अनुरोधों को सेवा देना जारी रखते हैं।
कार्यान्वयन:
- लिखें/अपडेट पथ:
src/sse/services/auth.ts::markAccountUnavailable() - खाता चयन/फिल्टरिंग:
src/sse/services/auth.ts::getProviderCredentials... - कूलडाउन गणना:
open-sse/services/accountFallback.ts::checkFallbackError() - सेटिंग्स:
src/lib/resilience/settings.ts
प्रदाता कनेक्शनों पर महत्वपूर्ण फ़ील्ड:
rateLimitedUntil;
testStatus: "unavailable";
lastError;
lastErrorType;
errorCode;
backoffLevel;
खाता चयन के दौरान, एक कनेक्शन को छोड़ दिया जाता है जबकि:
new Date(rateLimitedUntil).getTime() > Date.now();
कूलडाउन भी आलसी होते हैं: जब rateLimitedUntil अतीत में होता है, तो कनेक्शन फिर से योग्य हो जाता है। सफल उपयोग पर, clearAccountError() testStatus, rateLimitedUntil, त्रुटि फ़ील्ड, और backoffLevel को साफ करता है।
डिफ़ॉल्ट कनेक्शन कूलडाउन व्यवहार:
- OAuth बेस कूलडाउन:
5s। - API-key बेस कूलडाउन:
3s। - API-key
429को उपलब्ध होने पर अपस्ट्रीम पुनः प्रयास संकेतों (Retry-After, रीसेट हेडर, या पार्स करने योग्य रीसेट पाठ) को प्राथमिकता देनी चाहिए। - बार-बार पुनर्प्राप्त होने वाली विफलताएँ गुणांकित बैकऑफ़ का उपयोग करती हैं:
baseCooldownMs * 2 ** failureIndex;
एंटी-थंडरिंग-हर्ड गार्ड एक ही कनेक्शन पर समवर्ती विफलताओं को कूलडाउन को बार-बार बढ़ाने या backoffLevel को डबल-इंक्रीमेंट करने से रोकता है।
टर्मिनल राज्य कूलडाउन नहीं होते हैं। banned, expired, और credits_exhausted को तब तक अनुपलब्ध रहना चाहिए जब तक कि क्रेडेंशियल/सेटिंग्स में बदलाव न हो या एक ऑपरेटर उन्हें रीसेट न करे। टर्मिनल राज्यों को अस्थायी कूलडाउन स्थिति के साथ अधिलेखित न करें।
मॉडल लॉकआउट
दायरा: प्रदाता + कनेक्शन + मॉडल।
उद्देश्य: जब केवल एक मॉडल अनुपलब्ध या उस कनेक्शन के लिए कोटा-सीमित हो, तो पूरे कनेक्शन को अक्षम करने से बचें।
उदाहरण:
- प्रति-मॉडल कोटा प्रदाता जो
429लौटाते हैं। - एक गायब मॉडल के लिए
404लौटाने वाले स्थानीय प्रदाता। - प्रदाता-विशिष्ट मोड/मॉडल अनुमति विफलताएँ जैसे चयनित Grok मोड।
मॉडल लॉकआउट open-sse/services/accountFallback.ts में रहता है और उसी कनेक्शन को अन्य मॉडलों को सेवा देने की अनुमति देता है।
डिबगिंग मार्गदर्शन
- यदि एक प्रदाता के लिए सभी कुंजियाँ छोड़ दी जाती हैं, तो प्रदाता ब्रेकर स्थिति और प्रत्येक कनेक्शन के
rateLimitedUntil/testStatusकी जांच करें। - यदि एक प्रदाता रीसेट विंडो के बाद स्थायी रूप से बाहर दिखाई देता है, तो जांचें कि क्या कोड कच्ची
stateपढ़ रहा है बजाय इसके किgetStatus()/canExecute()का उपयोग कर रहा हो। - यदि एक प्रदाता कुंजी विफल होती है लेकिन अन्य काम करने चाहिए, तो प्रदाता ब्रेकर के बजाय कनेक्शन कूलडाउन को प्राथमिकता दें।
- यदि केवल एक मॉडल विफल होता है, तो कनेक्शन कूलडाउन के बजाय मॉडल लॉकआउट को प्राथमिकता दें।
- यदि एक स्थिति को स्वयं पुनर्प्राप्त करना चाहिए, तो इसमें भविष्य का टाइमस्टैम्प/रीसेट टाइमआउट होना चाहिए और एक रीड पथ होना चाहिए जो समाप्त स्थिति को ताज़ा करता है। स्थायी स्थितियों के लिए मैनुअल क्रेडेंशियल या कॉन्फ़िगरेशन परिवर्तनों की आवश्यकता होती है।
मुख्य सम्मेलन
कोड शैली
- 2 स्पेस, सेमीकोलन, डबल कोट्स, 100 कैरेक्टर चौड़ाई, es5 ट्रेलिंग कॉमा (lint-staged द्वारा Prettier के माध्यम से लागू)
- इम्पोर्ट्स: बाहरी → आंतरिक (
@/,@omniroute/open-sse) → सापेक्ष - नामकरण: फाइलें=camelCase/kebab, घटक=PascalCase, स्थिरांक=UPPER_SNAKE
- ESLint:
no-eval,no-implied-eval,no-new-func= हर जगह त्रुटि;no-explicit-any=open-sse/औरtests/में चेतावनी - TypeScript:
strict: false, लक्ष्य ES2022, मॉड्यूल esnext, समाधान बंडलर। स्पष्ट प्रकारों को प्राथमिकता दें।
डेटाबेस
- हमेशा
src/lib/db/डोमेन मॉड्यूल के माध्यम से जाएं — कभी भी रूट या हैंडलर्स में कच्चा SQL न लिखें - कभी भी
src/lib/localDb.tsमें लॉजिक न जोड़ें (केवल पुनः-निर्यात परत) - कभी भी
localDb.tsसे बैरल-इम्पोर्ट न करें — इसके बजाय विशिष्टdb/मॉड्यूल इम्पोर्ट करें - DB सिंगलटन:
getDbInstance()src/lib/db/core.tsसे (WAL जर्नलिंग) - माइग्रेशन:
src/lib/db/migrations/— संस्करणित SQL फ़ाइलें, idempotent, लेनदेन में चलाएं
त्रुटि प्रबंधन
- विशिष्ट त्रुटि प्रकारों के साथ try/catch, pino संदर्भ के साथ लॉग करें
- SSE स्ट्रीम में त्रुटियों को कभी न छिपाएं — सफाई के लिए abort संकेतों का उपयोग करें
- उचित HTTP स्थिति कोड लौटाएं (4xx/5xx)
सुरक्षा
- कभी भी
eval(),new Function(), या निहित eval का उपयोग न करें - सभी इनपुट को Zod स्कीमाओं के साथ मान्य करें
- विश्राम पर क्रेडेंशियल्स को एन्क्रिप्ट करें (AES-256-GCM)
- अपस्ट्रीम हेडर डिनायलिस्ट:
src/shared/constants/upstreamHeaders.ts— संपादन करते समय sanitize, Zod स्कीमाओं, और यूनिट परीक्षणों को संरेखित रखें - सार्वजनिक अपस्ट्रीम क्रेडेंशियल्स (Gemini/Antigravity/Windsurf-शैली OAuth client_id/secret + Firebase वेब कुंजी जो सार्वजनिक CLIs से निकाली गई हैं): ज़रूरी है कि इन्हें
resolvePublicCred()के माध्यम सेopen-sse/utils/publicCreds.tsमें एम्बेड किया जाए — कभी भी स्ट्रिंग लिटरल के रूप में नहीं। अनिवार्य पैटर्न के लिएdocs/security/PUBLIC_CREDS.mdदेखें। - त्रुटि प्रतिक्रियाएँ (HTTP / SSE / कार्यान्वयनकर्ता / MCP हैंडलर): ज़रूरी है कि इन्हें
buildErrorBody()याsanitizeErrorMessage()के माध्यम सेopen-sse/utils/error.tsसे रूट किया जाए — कभी भी कच्चाerr.stackयाerr.messageप्रतिक्रिया शरीर में न डालें।docs/security/ERROR_SANITIZATION.mdदेखें। - चर से बने शेल कमांड: जब
exec()/spawn()को एक स्क्रिप्ट के साथ कॉल करते हैं जिसे रनटाइम मानों की आवश्यकता होती है, तो उन्हेंenvविकल्प के माध्यम से पास करें (स्वचालित रूप से शेल-एस्केप किया गया) — कभी भी अविश्वसनीय/बाहरी पथों को स्क्रिप्ट शरीर में स्ट्रिंग-इंटरपोलेट न करें। संदर्भ:src/mitm/cert/install.ts::updateNssDatabases। - डिफ़ॉल्ट रूप से सुरक्षित पुस्तकालय (tldrsec/awesome-secure-defaults): नए सुरक्षा-संवेदनशील सतहों को जोड़ते समय कस्टम कार्यान्वयन के बजाय Helmet.js, DOMPurify, ssrf-req-filter, safe-regex, Google Tink को प्राथमिकता दें।
सामान्य संशोधन परिदृश्य
नया प्रदाता जोड़ना
src/shared/constants/providers.tsमें पंजीकरण करें (लोड पर Zod-मान्य)- यदि कस्टम लॉजिक की आवश्यकता हो तो
open-sse/executors/में कार्यान्वयनकर्ता जोड़ें (BaseExecutorका विस्तार करें) - यदि गैर-OpenAI प्रारूप है तो
open-sse/translator/में अनुवादक जोड़ें - यदि OAuth-आधारित है तो
src/lib/oauth/constants/oauth.tsमें OAuth कॉन्फ़िग जोड़ें — यदि अपस्ट्रीम CLI एक सार्वजनिक client_id/secret भेजता है, तोresolvePublicCred()के माध्यम से एम्बेड करें (देखेंdocs/security/PUBLIC_CREDS.md), कभी भी एक लिटरल के रूप में नहीं open-sse/config/providerRegistry.tsमें मॉडल पंजीकरण करेंtests/unit/में परीक्षण लिखें (यदि आपने एक नया एम्बेडेड डिफ़ॉल्ट जोड़ा है तो सार्वजनिकCreds आकार के सत्यापन को शामिल करें)
नया API रूट जोड़ना
src/app/api/v1/your-route/के तहत निर्देशिका बनाएंGET/POSTहैंडलर्स के साथroute.tsबनाएं- पैटर्न का पालन करें: CORS → Zod शरीर मान्यता → वैकल्पिक प्रमाणीकरण → हैंडलर प्रतिनिधित्व
- हैंडलर
open-sse/handlers/में जाता है (वहां से इम्पोर्ट करें, इनलाइन नहीं) - त्रुटि प्रतिक्रियाएँ
buildErrorBody()/errorResponse()का उपयोग करती हैंopen-sse/utils/error.tsसे (स्वचालित रूप से साफ़ किया गया — कभी भीerr.stackयाerr.messageकच्चा शरीर में न डालें)।docs/security/ERROR_SANITIZATION.mdदेखें। - परीक्षण जोड़ें — जिसमें कम से कम एक सत्यापन शामिल है कि त्रुटि प्रतिक्रियाएँ स्टैक ट्रेस लीक नहीं करतीं (
!body.error.message.includes("at /"))
नया DB मॉड्यूल जोड़ना
src/lib/db/yourModule.tsबनाएं —./core.tsसेgetDbInstanceइम्पोर्ट करें- अपने डोमेन तालिका(ओं) के लिए CRUD फ़ंक्शन निर्यात करें
- यदि नई तालिकाएँ आवश्यक हैं तो
src/lib/db/migrations/में माइग्रेशन जोड़ें src/lib/localDb.tsसे पुनः-निर्यात करें (केवल पुनः-निर्यात सूची में जोड़ें)- परीक्षण लिखें
नया MCP उपकरण जोड़ना
open-sse/mcp-server/tools/में Zod इनपुट स्कीमा + असिंक्रोनस हैंडलर के साथ उपकरण परिभाषा जोड़ें- उपकरण सेट में पंजीकरण करें (
createMcpServer()द्वारा वायर्ड) - उपयुक्त स्कोप(ओं) को असाइन करें
- परीक्षण लिखें (उपकरण आह्वान
mcp_auditतालिका में लॉग किया गया)
नया A2A कौशल जोड़ना
src/lib/a2a/skills/में कौशल बनाएं (5 पहले से मौजूद हैं: स्मार्ट-रूटिंग, कोटा-प्रबंधन, प्रदाता-खोज, लागत-विश्लेषण, स्वास्थ्य-रिपोर्ट)- कौशल कार्य संदर्भ (संदेश, मेटाडेटा) प्राप्त करता है → संरचित परिणाम लौटाता है
src/lib/a2a/taskExecution.tsमेंA2A_SKILL_HANDLERSमें पंजीकरण करेंsrc/app/.well-known/agent.json/route.tsमें उजागर करें (एजेंट कार्ड)tests/unit/में परीक्षण लिखेंdocs/frameworks/A2A-SERVER.mdकौशल तालिका में दस्तावेज़ करें
नया क्लाउड एजेंट जोड़ना
src/lib/cloudAgent/agents/मेंCloudAgentBaseका विस्तार करते हुए एजेंट क्लास बनाएं (3 पहले से मौजूद हैं: codex-cloud, devin, jules)createTask,getStatus,approvePlan,sendMessage,listSourcesको लागू करेंsrc/lib/cloudAgent/registry.tsमें पंजीकरण करें- यदि आवश्यक हो तो OAuth/क्रेडेंशियल्स प्रबंधन जोड़ें (
src/lib/oauth/providers/) - परीक्षण + दस्तावेज़
docs/frameworks/CLOUD_AGENT.mdमें
नया गार्डरेल / इवैल / कौशल / वेबहुक इवेंट जोड़ना
- गार्डरेल:
src/lib/guardrails/→ दस्तावेज़:docs/security/GUARDRAILS.md - इवैल सूट:
src/lib/evals/→ दस्तावेज़:docs/frameworks/EVALS.md - कौशल (सैंडबॉक्स):
src/lib/skills/→ दस्तावेज़:docs/frameworks/SKILLS.md - वेबहुक इवेंट:
src/lib/webhookDispatcher.ts→ दस्तावेज़:docs/frameworks/WEBHOOKS.md
संदर्भ दस्तावेज़
किसी भी गैर-तुच्छ परिवर्तन के लिए, पहले संबंधित गहराई से अध्ययन करें:
| क्षेत्र | दस्तावेज़ |
|---|---|
| रेपो नेविगेशन | docs/architecture/REPOSITORY_MAP.md |
| आर्किटेक्चर | docs/architecture/ARCHITECTURE.md |
| इंजीनियरिंग संदर्भ | docs/architecture/CODEBASE_DOCUMENTATION.md |
| ऑटो-कॉम्बो (9-फैक्टर स्कोरिंग, 14 रणनीतियाँ) | docs/routing/AUTO-COMBO.md |
| सहनशीलता (3 तंत्र) | docs/architecture/RESILIENCE_GUIDE.md |
| तर्क पुनरावृत्ति | docs/routing/REASONING_REPLAY.md |
| कौशल ढांचा | docs/frameworks/SKILLS.md |
| मेमोरी प्रणाली (FTS5 + Qdrant) | docs/frameworks/MEMORY.md |
| क्लाउड एजेंट | docs/frameworks/CLOUD_AGENT.md |
| गार्डरेल्स (PII / इंजेक्शन / दृष्टि) | docs/security/GUARDRAILS.md |
| सार्वजनिक अपस्ट्रीम क्रेडेंशियल्स (जेमिनी/आदि) | docs/security/PUBLIC_CREDS.md |
| त्रुटि संदेश स्वच्छता | docs/security/ERROR_SANITIZATION.md |
| मूल्यांकन | docs/frameworks/EVALS.md |
| अनुपालन / ऑडिट | docs/security/COMPLIANCE.md |
| वेबहुक्स | docs/frameworks/WEBHOOKS.md |
| प्राधिकरण पाइपलाइन | docs/architecture/AUTHZ_GUIDE.md |
| स्टील्थ (TLS / फिंगरप्रिंट) | docs/security/STEALTH_GUIDE.md |
| एजेंट प्रोटोकॉल (A2A / ACP / क्लाउड) | docs/frameworks/AGENT_PROTOCOLS_GUIDE.md |
| MCP सर्वर | docs/frameworks/MCP-SERVER.md |
| A2A सर्वर | docs/frameworks/A2A-SERVER.md |
| API संदर्भ + OpenAPI | docs/reference/API_REFERENCE.md + docs/reference/openapi.yaml |
| प्रदाता कैटलॉग (स्वतः उत्पन्न) | docs/reference/PROVIDER_REFERENCE.md |
| रिलीज़ प्रवाह | docs/ops/RELEASE_CHECKLIST.md |
परीक्षण
| क्या | कमांड |
|---|---|
| यूनिट परीक्षण | npm run test:unit |
| एकल फ़ाइल | node --import tsx/esm --test tests/unit/file.test.ts |
| विटेस्ट (MCP, autoCombo) | npm run test:vitest |
| E2E (Playwright) | npm run test:e2e |
| प्रोटोकॉल E2E (MCP+A2A) | npm run test:protocols:e2e |
| पारिस्थितिकी | npm run test:ecosystem |
| कवरेज गेट | npm run test:coverage (75/75/75/70 — स्टेटमेंट/लाइन/फंक्शन/ब्रांच) |
| कवरेज रिपोर्ट | npm run coverage:report |
PR नियम: यदि आप src/, open-sse/, electron/, या bin/ में उत्पादन कोड बदलते हैं, तो आपको उसी PR में परीक्षण शामिल करना या अपडेट करना होगा।
परीक्षण परत प्राथमिकता: यूनिट पहले → एकीकरण (मल्टी-मॉड्यूल या DB स्थिति) → E2E (UI/कार्यप्रवाह केवल)। बग पुनरुत्पादन को स्वचालित परीक्षणों के रूप में कोडित करें पहले या ठीक करने के साथ।
कोपायलट कवरेज नीति: जब एक PR उत्पादन कोड को बदलता है और कवरेज 75% (स्टेटमेंट/लाइन/फंक्शन) या 70% (ब्रांच) से नीचे है, तो केवल रिपोर्ट न करें — परीक्षण जोड़ें या अपडेट करें, कवरेज गेट को फिर से चलाएं, फिर पुष्टि के लिए पूछें। PR रिपोर्ट में चलाए गए कमांड, बदले गए परीक्षण फ़ाइलें, और अंतिम कवरेज परिणाम शामिल करें।
गिट कार्यप्रवाह
# कभी भी सीधे मुख्य में कमिट न करें
git checkout -b feat/your-feature
git commit -m "feat: अपने परिवर्तन का वर्णन करें"
git push -u origin feat/your-feature
ब्रांच उपसर्ग: feat/, fix/, refactor/, docs/, test/, chore/
कमिट प्रारूप (परंपरागत कमिट): feat(db): सर्किट ब्रेकर जोड़ें — स्कोप: db, sse, oauth, डैशबोर्ड, api, cli, docker, ci, mcp, a2a, memory, skills
हस्की हुक:
- pre-commit: lint-staged +
check-docs-sync+check:any-budget:t11 - pre-push:
npm run test:unit
वातावरण
- रनटाइम: Node.js ≥20.20.2 <21 | | ≥22.22.2 <23 | | ≥24 <25, ES मॉड्यूल
- TypeScript: 5.9+, लक्ष्य ES2022, मॉड्यूल esnext, समाधान बंडलर
- पथ उपनाम:
@/*→src/,@omniroute/open-sse→open-sse/,@omniroute/open-sse/*→open-sse/* - डिफ़ॉल्ट पोर्ट: 20128 (API + डैशबोर्ड एक ही पोर्ट पर)
- डेटा निर्देशिका:
DATA_DIRenv var, डिफ़ॉल्ट रूप से~/.omniroute/ - मुख्य env vars:
PORT,JWT_SECRET,API_KEY_SECRET,INITIAL_PASSWORD,REQUIRE_API_KEY,APP_LOG_LEVEL - सेटअप:
cp .env.example .envफिरJWT_SECRET(openssl rand -base64 48) औरAPI_KEY_SECRET(openssl rand -hex 32) उत्पन्न करें
कठोर नियम
- कभी भी रहस्य या क्रेडेंशियल्स को कमिट न करें
- कभी भी
localDb.tsमें लॉजिक न जोड़ें - कभी भी
eval()/new Function()/ निहित eval का उपयोग न करें - कभी भी सीधे
mainमें कमिट न करें - कभी भी रूट में कच्चा SQL न लिखें —
src/lib/db/मॉड्यूल का उपयोग करें - कभी भी SSE स्ट्रीम में त्रुटियों को चुपचाप न निगलें
- हमेशा Zod स्कीमा के साथ इनपुट को मान्य करें
- उत्पादन कोड बदलते समय हमेशा परीक्षण शामिल करें
- कवरेज को ≥75% (स्टेटमेंट, लाइन, फंक्शन) / ≥70% (ब्रांच) पर बनाए रखना चाहिए। वर्तमान मापी गई: ~82%।
- बिना स्पष्ट ऑपरेटर अनुमोदन के हस्की हुक को बायपास न करें (
--no-verify,--no-gpg-sign)। - कभी भी सार्वजनिक अपस्ट्रीम OAuth client_id/secret या Firebase Web कुंजी को स्ट्रिंग लिटेरल के रूप में न embed करें — हमेशा
resolvePublicCred()(open-sse/utils/publicCreds.ts) के माध्यम से जाएं। देखेंdocs/security/PUBLIC_CREDS.md। - कभी भी HTTP / SSE / कार्यान्वयन प्रतिक्रियाओं में कच्चा
err.stack/err.messageन लौटाएं — हमेशाbuildErrorBody()याsanitizeErrorMessage()(open-sse/utils/error.ts) के माध्यम से रूट करें। देखेंdocs/security/ERROR_SANITIZATION.md। - कभी भी बाहरी पथों या रनटाइम मानों को
exec()/spawn()को पास किए गए शेल स्क्रिप्ट में स्ट्रिंग-इंटरपोलेट न करें — इसके बजायenvविकल्प के माध्यम से पास करें। संदर्भ:src/mitm/cert/install.ts::updateNssDatabases। - कभी भी CodeQL / Secret-Scanning अलर्ट को खारिज न करें बिना (a) पहले ऊपर पैटर्न दस्तावेज़ों की जांच किए कि क्या सहायक लागू होता है, और (b) खारिज़ टिप्पणी में तकनीकी औचित्य को रिकॉर्ड किए बिना। मिसाल:
js/stack-trace-exposureको कॉलसाइट्स पर उठाया गया जो पहले से हीsanitizeErrorMessage()के माध्यम से रूट करते हैं, यह एक ज्ञात CodeQL सीमा है (कस्टम सैनिटाइज़र मान्यता प्राप्त नहीं हैं) — इसेfalse positiveके रूप में खारिज करें जोdocs/security/ERROR_SANITIZATION.mdका संदर्भ देता है। - कभी भी उन रूट्स को उजागर न करें जो चाइल्ड प्रोसेस को स्पॉन करते हैं (
/api/mcp/,/api/cli-tools/runtime/) बिनाsrc/server/authz/routeGuard.tsमेंisLocalOnlyPath()वर्गीकरण के। लूपबैक प्रवर्तन किसी भी प्रमाणीकरण जांच से पहले बिना शर्त होता है — टनल के माध्यम से लीक किया गया JWT प्रक्रिया स्पॉनिंग को ट्रिगर नहीं कर सकता। देखेंdocs/security/ROUTE_GUARD_TIERS.md। - कभी भी
Co-Authored-Byट्रेलर्स शामिल न करें जो AI सहायक, LLM या स्वचालन खाते को क्रेडिट देते हैं (जैसे "Claude", "GPT", "Copilot", "Bot" युक्त नाम;anthropic.com/openai.com/ बॉट-स्वामित्व वालेnoreply.github.comपतों पर ईमेल)। ऐसे ट्रेलर्स GitHub पर बॉट खाते में कमिट एट्रिब्यूशन रूट करते हैं, PR इतिहास में वास्तविक लेखक (diegosouzapw) को छिपाते हैं। मानव सहयोगी — upstream PR लेखकों और OmniRoute में पोर्ट किए जा रहे issue रिपोर्टरों सहित — मानकCo-authored-by: Name <email>ट्रेलर्स के साथ क्रेडिट प्राप्त कर सकते हैं और चाहिए; upstream-port वर्कफ़्लो (/port-upstream-features,/port-upstream-issues) इस पर निर्भर हैं।