OctoHub से मिलिए: आपके एजेंट जिस भी LLM को कॉल करें, उसके लिए एक ही प्रवेश द्वार

आपके एजेंट ने अभी एक टास्क चलाया। उसने चालीस मॉडल कॉल कीं। कुछ एक लोकल Ollama मशीन पर गईं, कुछ Anthropic पर, और एक OpenAI पर क्योंकि लोकल मॉडल लंबे कॉन्टेक्स्ट पर अटक गया। टास्क खत्म हो गया। अब मुझे तीन सवालों के जवाब दीजिए: उसने ठीक-ठीक क्या भेजा, उसकी कीमत क्या रही, और असल में किस अपस्ट्रीम ने जवाब दिया।

अगर आप हमारी तरह थे, तो ईमानदार जवाब है "मुझे print स्टेटमेंट जोड़कर इसे दोबारा चलाना पड़ेगा।" प्रोवाइडर के डैशबोर्ड आपको अपना हिस्सा दिखाते हैं। आपके एजेंट के लॉग आपको अपना हिस्सा दिखाते हैं। कोई भी आपको वह पूरा अनुरोध नहीं दिखाता जैसा वह तार पर गया था, इस टैग के साथ कि कौन-सी कुंजी ने उसे जारी किया और कौन-से प्रोवाइडर ने उसे उठाया। सबसे उपयोगी दृश्य — एक ही पैन से हर अनुरोध — वही है जो कोई नहीं देता, क्योंकि अनुरोधों के गुज़रने के लिए कोई एक जगह ही नहीं है।

OctoHub वही एक जगह है। यह एक सेल्फ-होस्टेड LLM प्रॉक्सी है जिसे आप अपने एजेंट्स के आगे चलाते हैं। वे एक एंडपॉइंट से बात करते हैं; OctoHub उससे बात करता है जिसे आप कहते हैं, और बीच में जो कुछ होता है वह सब लिख लेता है। आज हम इसे ओपन-सोर्स कर रहे हैं।


यह क्या है, एक आरेख में

            ┌──────────────────┐
 agent   →  │  OctoHub proxy   │  →  openai
            │  (Rust / hyper)  │  →  anthropic
            │                  │  →  ollama (your GPU)
            └──────────────────┘  →  openrouter
                     │
                     └─→ your DB (SQLite / MySQL / PostgreSQL)
                         (api_keys, completions, embeddings)

hyper पर बना एक अकेला Rust बाइनरी। क्लाइंट एक HTTP एंडपॉइंट पर हिट करते हैं। प्रॉक्सी मॉडल का नाम हल करता है, एक अपस्ट्रीम चुनता है, कॉल को octolib के ज़रिए आगे भेजता है — हमारी LLM क्लाइंट लाइब्रेरी, वही जिसे Muvon का हर टूल मॉडलों से बात करने के लिए इस्तेमाल करता है — और अनुरोध, प्रतिक्रिया, टोकन गिनती और लेटेंसी को सहेजता है। प्रॉक्सी खुद अनुरोधों के बीच स्टेटलेस है। स्टेट दो जगहों पर रहता है: कॉन्फ़िगरेशन के लिए octohub.toml, और कुंजियों, लॉग और उपयोग के लिए एक डेटाबेस।

जानबूझकर यह कई चीज़ें नहीं है। यह चैट UI नहीं है — अपना एप्लिकेशन इस पर ताक दीजिए। यह कोई सिमैंटिक राउटर नहीं है जो किसी प्रॉम्प्ट के लिए "सर्वश्रेष्ठ" मॉडल चुने; मॉडल चुनना कॉल करने वाले का काम है। यह वेक्टर स्टोर नहीं है; एम्बेडिंग आर-पार गुज़रती हैं और लॉग होती हैं, पर OctoHub उन्हें इंडेक्स नहीं करता। यह ऑथेंटिकेशन, लॉगिंग, लोड बैलेंसिंग और एक स्थिर इंटरफ़ेस जोड़ता है। यह प्रोवाइडर जो लौटाते हैं उससे चतुराई करने की कोशिश नहीं करता — हर सार्थक फ़ील्ड क्लाइंट को जस का तस वापस आता है।


हमने इसे क्यों बनाया

हम प्रॉक्सी बनाने नहीं निकले थे। हम Octomind, अपने एजेंट रनटाइम, को मॉडलों के मिश्रण पर चला रहे थे — सस्ते उच्च-वॉल्यूम काम के लिए अपनी ही GPU पर एक सेल्फ-होस्टेड बेड़ा, और कठिन काम के लिए फ्रंटियर API। सेटअप काम करता था। जो काम नहीं करता था वह था उसे देख पाना

जिस पल आपके एक एप्लिकेशन के पीछे एक से ज़्यादा मॉडल हो जाते हैं, आप वह एकल पैन खो देते हैं। हर प्रोवाइडर का अपना डैशबोर्ड है, अपनी टोकन गिनती है, "अनुरोध" क्या है इसका अपना विचार है। आपके एजेंट के अपने लॉग हैं, जो बताते हैं कि उसने जो भेजा वह उसने क्या समझा। जब कोई रन उम्मीद से ज़्यादा महँगा पड़ता है, या कोई मॉडल कचरा लौटाने लगता है, तो आप तीन अधूरी कहानियों को सिलते हैं और जोड़ों पर अनुमान लगाते हैं।

हमने उस विशेष तकलीफ़ के बारे में और लिखा — यह देखना चाहना कि एजेंट ने असल में क्या किया, न कि उसने क्या दावा किया — उस ऑब्ज़र्वेबिलिटी में जो हम चाहते थे। OctoHub उसका इंफ्रास्ट्रक्चर-स्तर का जवाब है। रास्ते में एक प्रॉक्सी रख दीजिए और एकल पैन रचना से ही मौजूद हो जाता है: सचमुच एक ही जगह है जहाँ से हर अनुरोध गुज़रता है, इसलिए उसे रिकॉर्ड करने की भी एक ही जगह है।

दूसरी वजह लोड बैलेंसिंग थी। हम पहले से ही एक एजेंट को कई मॉडलों पर चला रहे थे हाथ से — कॉन्फ़िग अदला-बदली, एनवायरनमेंट वेरिएबल, हर रन पर मॉडल का नाम बदलना। हम एक मॉडल अलियास चाहते थे जिसका मतलब हो "इन अपस्ट्रीमों में से कोई भी, तेरी मर्ज़ी", और एक कॉन्करेंसी सीमा ताकि एजेंट कॉलों का एक झोंका लोकल GPU मशीन को न पिघला दे। ये दोनों एक प्रॉक्सी की जगह हैं, हर क्लाइंट में बिखरी हुई नहीं।


एक अनुरोध इसमें से कैसे बहता है

एक POST /v1/completions लीजिए। OctoHub उसके साथ यह करता है:

  1. ऑथेंटिकेट। Authorization: Bearer टोकन api_keys टेबल से एक क्लाइंट API कुंजी है। OctoHub उसे ढूँढता है, जाँचता है कि वह सक्रिय है, और अनुरोध को कुंजी ID से टैग करता है। (अगर आप सर्वर को बिना मास्टर कुंजी के शुरू करते हैं, तो केवल एडमिन API बंद होता है — शुरू में एक चेतावनी प्रिंट होती है; completion और embedding कॉल के लिए अब भी एक वैध क्लाइंट कुंजी चाहिए।)
  2. अनुमति-सूची जाँचें। क्लाइंट कुंजियाँ मॉडलों के एक सेट तक सीमित की जा सकती हैं। ["gpt", "anthropic:claude-haiku-4-5"] तक सीमित कुंजी अगर कुछ और माँगे तो उसे 403 मिलता है।
  3. मॉडल हल करें। अगर model फ़ील्ड [models] से एक अलियास है, तो OctoHub उसे एक provider:model स्ट्रिंग में फैला देता है। अगर वह पहले से एक नंगा provider:model है, तो वह सीधा गुज़र जाता है। जो अलियास एक सूची में मैप होते हैं, वे एक यादृच्छिक प्रविष्टि से शुरू होकर पहले प्रोवाइडर को लेते हैं जो स्वीकार कर सके — यही लोड बैलेंसिंग है।
  4. प्रोवाइडर परमिट हासिल करें। अगर आपने उस प्रोवाइडर के लिए कॉन्करेंसी सीमा तय की है, तो अनुरोध एक खाली स्लॉट का इंतज़ार करता है। स्लॉट नहीं, तो 429 नहीं — HTTP कनेक्शन बस खुला रहता है जब तक एक खाली न हो जाए — क़तार टाइमआउट तक (डिफ़ॉल्ट 60 सेकंड), जिसके बाद 503 मिलता है। जानबूझकर थ्रॉटलिंग, कतार-प्रतीक्षा समय के रूप में रिकॉर्ड।
  5. अपस्ट्रीम को कॉल करें octolib के ज़रिए, एक कॉन्फ़िगर करने योग्य ऑपरेशन डेडलाइन के साथ।
  6. सहेजें और जवाब दें। पूरा अनुरोध, प्रतिक्रिया, टोकन गिनती, लागत, हल किया गया प्रोवाइडर और लेटेंसी completions टेबल में जाते हैं। क्लाइंट को अपस्ट्रीम का जवाब जस का तस मिलता है, साथ में एक X-Request-Id हेडर।

वह X-Request-Id जोड़ने वाली कुंजी है। यह या तो आपका दिया मान है (मान्य किया गया, वापस लौटाया गया) या एक ताज़ा ULID। यह उस अनुरोध की हर लॉग लाइन पर req_id के रूप में दिखता है। एक एरर रिस्पॉन्स लीजिए, हेडर पकड़िए, अपने लॉग पर grep कीजिए — आपके पास पूरी कहानी है।


मॉडल अलियास और लोड बैलेंसिंग

[models] सेक्शन वह जगह है जहाँ एक नाम कई अपस्ट्रीमों में पंखे की तरह फैलता है:

[models]
# एक अलियास, एक अपस्ट्रीम
"sonnet"  = ["anthropic:claude-sonnet-5"]

# एक अलियास, कई अपस्ट्रीम — OctoHub हर अनुरोध पर एक यादृच्छिक रूप से चुनता है
"workhorse" = ["ollama:kimi-k2.6", "ollama:minimax-m3", "openrouter:google/gemini-3.1-pro-preview"]

[embedding_models]
"voyage" = ["voyage:voyage-4"]

workhorse माँगने वाले क्लाइंट को तीनों में से एक मिलता है — OctoHub एक यादृच्छिक प्रविष्टि से शुरू होता है और पहले प्रोवाइडर को लेता है जिसकी रेट विंडो अनुरोध स्वीकार कर सके। यही पूरा लोड-बैलेंसिंग मॉडल है — सरल, पूर्वानुमेय, और एजेंट ट्रैफ़िक को एक बेड़े या कुंजियों में बाँटने के लिए ठीक उतना ही जितना चाहिए, बिना किसी अलग राउटर के। आज कोई वेटेड रूटिंग नहीं है; एरर कूलडाउन पर प्रोवाइडर को स्वस्थ वालों के पीछे रखा जाता है, और चेन जारी रखने वाले अनुरोध उसी प्रोवाइडर पर टिकते हैं जिसने पिछला टर्न सर्व किया। हम उसका ईमानदार संस्करण भेजना पसंद करते हैं, न कि उससे ज़्यादा चतुर शेड्यूलर का संकेत देना जितना मौजूद है।

क्लाइंट अलियास को पूरी तरह दरकिनार करके openai:gpt-5.5 जैसा नंगा provider:model भी भेज सकते हैं। अलियास टेबल एक सुविधा है, कोई गेट नहीं — गेट तो प्रति-कुंजी अनुमति-सूची है।


auto मॉडल: कौन सा नहीं, क्यों बताइए

0.6.0 से मॉडल चुनने का एक दूसरा तरीका है, और हमारे अपने एजेंट सबसे ज़्यादा यही इस्तेमाल करते हैं। मॉडल का नाम लेने के बजाय, क्लाइंट "model": "auto" के साथ एक X-Model-Purpose हेडर भेजता है — कोई भी स्ट्रिंग जो आप चाहें — और OctoHub उस उद्देश्य को एक अलियास में हल कर देता है:

[auto]
default = "workhorse"
compression = "cheap"
supervisor = "sonnet"

उद्देश्य पदानुक्रमित होते हैं, - पर विभाजित: supervisor-gate पहले supervisor पर, फिर default पर गिरता है। एक supervisor पंक्ति हर supervisor-* उद्देश्य को तब तक कवर करती है जब तक आप कोई खास पिन न कर दें — आप ठीक उतनी ही पंक्तियाँ बनाते हैं जितनी आपकी राय है। कोई गायब या गलत-वर्तनी वाला उद्देश्य default पर डिग्रेड हो जाता है, कभी फेल नहीं होता।

इतनी मेहनत क्यों? क्योंकि कॉल करने वाला आमतौर पर जानता है कि वह किस तरह की कॉल कर रहा है — कम्प्रेशन पास, गेट चेक, मुख्य लूप — और ऑपरेटर जानता है कि उस तरह की कॉल किस टियर की हकदार है। उद्देश्य-आधारित रूटिंग यह फैसला प्रॉक्सी कॉन्फ़िग में रखती है (या PUT /v1/admin/owners/:owner/auto से प्रति-ओनर ओवरराइड मैप में, जो कॉन्फ़िग फ़्लोर को पूरी तरह पछाड़ देता है), बजाय मॉडल नामों को एजेंट में हार्डकोड करने के। Octomind डिफ़ॉल्ट रूप से main, compression और supervisor-* परिवार भेजता है।


प्रति-प्रोवाइडर कॉन्करेंसी

आपका फ्रंटियर API बत्तीस समानांतर अनुरोध बिना पलक झपकाए ले सकता है। Ollama चलाने वाली आपकी अकेली GPU मशीन नहीं ले सकती। इसलिए OctoHub प्रति प्रोवाइडर इन-फ्लाइट अनुरोधों पर सीमा लगाता है:

[providers.ollama]
concurrency = 5

[providers.openai]
concurrency = 32

सीमा से ज़्यादा अनुरोध OctoHub प्रोसेस के अंदर कतार में लगते हैं — क्लाइंट कनेक्शन तब तक ब्लॉक रहता है जब तक एक स्लॉट न खुले। जिन प्रोवाइडरों को आप सूचीबद्ध नहीं करते, वे बिना सीमा के चलते हैं। लिमिटर प्रोसेस-लोकल है और completions तथा embeddings को साथ गिनता है, क्योंकि दोनों एक ही अपस्ट्रीम कनेक्शन से बहते हैं। यह प्रति प्रोवाइडर एक सेमाफोर है, कुछ अनोखा नहीं, पर इसका मतलब है कि चालीस कॉल फैलाने वाला एजेंट उस मॉडल सर्वर को नहीं गिराएगा जिस पर वे उतरती हैं।

कॉन्करेंसी ही एकमात्र नॉब नहीं है। हर प्रोवाइडर फिक्स्ड-विंडो रेट लिमिट भी लेता है — requests_per_minute, tokens_per_minute, requests_per_day, tokens_per_day — और मल्टी-अपस्ट्रीम अलियास किसी विंडो के भर जाने पर अगले कैंडिडेट पर घूम जाता है। यही वे "रेट विंडो" हैं जिन्हें अलियास चुनने वाला जाँचता है: किसी प्रोवाइडर का दैनिक टोकन बजट खत्म हो जाना अनुरोध को फेल नहीं करता, बस ट्रैफ़िक को अगले उस अपस्ट्रीम पर शिफ्ट कर देता है जिसके पास अभी मार्जिन है।


जो ऑब्ज़र्वेबिलिटी आपको सचमुच मिलती है

यही वह हिस्सा है जिसके लिए हमने OctoHub बनाया, तो इसकी दो सतहें हैं।

संरचित लॉग stdout पर — अगर आप TTY पर हैं तो सुंदर, वरना JSON। हर पूर्ण अनुरोध एक लाइन निकालता है:

{
	"level": "INFO",
	"message": "request completed",
	"req_id": "01HMQGSB3R",
	"route": "/v1/completions",
	"status": 200,
	"dur_ms": 1523,
	"api_key_id": 1,
	"model": "workhorse",
	"provider": "ollama",
	"queued_ms": 0,
	"tok_in": 56,
	"tok_out": 120
}

आप वह कुंजी देखते हैं जिसने इसे जारी किया, मॉडल का वह नाम जो क्लाइंट ने माँगा, वह प्रोवाइडर जिसने असल में जवाब दिया, वह कितनी देर कतार में रहा, कितना समय लगा, और इनपुट तथा आउटपुट टोकन। provider फ़ील्ड इस सवाल का जवाब है कि "यादृच्छिक चुनाव किस अपस्ट्रीम पर गिरा" — बिना कुछ दोबारा चलाए।

Prometheus मेट्रिक्स एक अलग पोर्ट पर (डिफ़ॉल्ट 127.0.0.1:9090, GET /metrics)। सब पर octohub_ उपसर्ग है:

मेट्रिक यह आपको क्या बताती है
octohub_requests_total route, method, status के अनुसार अनुरोध मात्रा
octohub_request_duration_seconds छोर-से-छोर लेटेंसी हिस्टोग्राम
octohub_completions_total model, provider, status के अनुसार completion मात्रा
octohub_completion_tokens_total model और provider के अनुसार इन/आउट टोकन
octohub_provider_queue_wait_seconds कॉन्करेंसी परमिट के इंतज़ार में बीता समय
octohub_provider_in_flight अभी प्रत्येक provider पर सक्रिय अनुरोध

कतार-प्रतीक्षा हिस्टोग्राम संतृप्ति का अग्रिम संकेतक है — जब P99 ऊपर चढ़ता है, तो किसी अनुरोध के टाइमआउट होने से पहले ही आपका बेड़ा अड़चन बन जाता है। PromQL की कुछ लाइनें आपको मॉडल के अनुसार एरर दर और प्रोवाइडर के अनुसार आउटपुट टोकन/सेकंड देती हैं। per_key = true चालू कीजिए और completion मेट्रिक्स को एक api_key_id लेबल मिल जाता है, ताकि आप प्रति क्लाइंट बिलिंग या लागत आवंटन कर सकें। (हज़ारों कुंजियाँ जारी करते हैं तो कार्डिनैलिटी का ध्यान रखें।)

पूरे रिकॉर्ड के लिए — एग्रीगेट नहीं, बल्कि प्रॉम्प्ट और प्रतिक्रिया के असली बाइट — एडमिन API completions का कच्चा इतिहास सीधे डेटाबेस से परोसता है।


मल्टी-टेनेंट कुंजियाँ और एडमिन API

OctoHub के पास दो ऑथेंटिकेशन परतें हैं। मास्टर कुंजी (octohub.toml में तय) एडमिन API की रक्षा करती है। क्लाइंट कुंजियाँ — उसी एडमिन API से जारी, डेटाबेस में संग्रहित — completion और embedding एंडपॉइंट को ऑथेंटिकेट करती हैं। हर completion जारी करने वाली कुंजी से टैग होता है, और यही चीज़ प्रति-टेनेंट उपयोग ट्रैकिंग को काम करने लायक बनाती है।

रोज़मर्रा के कामकाज के लिए एक shell रैपर है, octohub-admin.sh:

export OCTOHUB_MASTER_KEY=your-master-secret

# एक क्लाइंट कुंजी जारी करें, दो मॉडलों तक सीमित
./octohub-admin.sh keys create ci-pipeline --allowed-models gpt,anthropic:claude-haiku-4-5

# कुंजी 1 और 2 के लिए दैनिक उपयोग
./octohub-admin.sh usage --bucket day --key 1,2

# अंतिम 20 कच्चे completions निकालें — पूरा इनपुट और आउटपुट
./octohub-admin.sh completions --limit 20

कुंजियाँ रद्द होती हैं, कभी हटाई नहीं जातीं — उपयोग रिकॉर्ड कुंजी ID से जुड़े होते हैं, इसलिए इतिहास बचा रहता है। उपयोग hour, day, week या month के अनुसार समेटा जाता है, कुंजी और समय-सीमा से फ़िल्टर करने योग्य। यही डेटा सादे HTTP के रूप में भी उपलब्ध है अगर आप स्क्रिप्ट इस्तेमाल नहीं करना चाहते।

दो और ऑपरेशनल सतहें जानने लायक हैं। GET /v1/admin/status असली ट्रैफ़िक से देखी गई प्रति-मॉडल हेल्थ बताता है — कोई सिंथेटिक प्रोब नहीं, इसलिए एक हिचकी आपके डैशबोर्ड पर लाल बत्ती नहीं जलाती। और प्रोसेस को SIGHUP भेजने से octohub.toml वहीं रीलोड हो जाता है — नए अलियास, नई सीमाएँ, बिना रीस्टार्ट।


इसे 5 मिनट में चलाएँ

OctoHub एक अकेला बाइनरी है। इसे बनाइए, एक कॉन्फ़िग लिखिए, इसे चलाइए, एक कुंजी जारी कीजिए।

# 1. स्रोत से बनाएँ
git clone https://github.com/Muvon/octohub
cd octohub && cargo build --release

एक न्यूनतम octohub.toml लिखिए:

[server]
host = "127.0.0.1"
port = 8080
api_key = "your-master-secret"        # auth + एडमिन API सक्षम करता है
db_url = "sqlite://octohub.db"         # पहले रन पर स्कीमा अपने-आप बनता है

[models]
"workhorse" = ["ollama:kimi-k2.6", "openrouter:google/gemini-3.1-pro-preview"]

[metrics]
enabled = true
bind = "127.0.0.1:9090"

[providers.ollama]
concurrency = 5

इसे चलाइए और एक क्लाइंट कुंजी बनाइए:

# 2. सर्वर शुरू करें (अगर कॉन्फ़िग cwd में नहीं है तो -c से इंगित करें)
./target/release/octohub

# 3. एक क्लाइंट कुंजी जारी करें
curl -X POST http://127.0.0.1:8080/v1/admin/keys \
  -H "Authorization: Bearer your-master-secret" \
  -H "Content-Type: application/json" \
  -d '{"name": "my-app"}'
# → {"id": 1, "key": "abc...xyz", ...}   ← इसे सहेजें, यह एक ही बार दिखता है

# 4. प्रॉक्सी के ज़रिए एक completion बनाएँ
curl -X POST http://127.0.0.1:8080/v1/completions \
  -H "Authorization: Bearer abc...xyz" \
  -H "Content-Type: application/json" \
  -d '{"model": "workhorse", "input": "Explain Rust in one sentence."}'

डेटाबेस SQLite के रूप में शुरू होता है — कोई सेटअप नहीं। जब आप इससे आगे बढ़ें तो db_url को MySQL या PostgreSQL की ओर इंगित कीजिए; स्कीमा पहले कनेक्शन पर अपने-आप बनता है। प्रोवाइडर API कुंजियाँ (OPENAI_API_KEY, ANTHROPIC_API_KEY और साथी) एनवायरनमेंट में रहती हैं, octolib द्वारा ठीक वैसे पढ़ी जाती हैं जैसे प्रोवाइडर उम्मीद करते हैं।

OctoHub POST /v1/chat/completions पर क्लासिक OpenAI Chat Completions भी बोलता है, तो कोई भी OpenAI-संगत SDK या टूल इसे एक ड्रॉप-इन base URL की तरह इंगित कर सकता है। (एक ईमानदार चेतावनी: स्ट्रीमिंग लागू नहीं है — "stream": true वाले अनुरोध को 501 मिलता है।)


Octomind को इस पर इंगित करना

OctoHub और Octomind एक-दूसरे के लिए बने हैं, और octolib एक नेटिव octohub: प्रोवाइडर के साथ आता है — कोई OpenAI-संगत शिम नहीं, यह सीधे OctoHub की Responses API बोलता है। दो एनवायरनमेंट वेरिएबल उन्हें जोड़ते हैं:

export OCTOHUB_API_URL=http://127.0.0.1:8080   # आपका OctoHub सर्वर
export OCTOHUB_API_KEY=abc...xyz               # आपकी जारी की हुई क्लाइंट कुंजी

अब octohub:<alias> रूप में Octomind का कोई भी मॉडल संदर्भ प्रॉक्सी के ज़रिए रूट होता है:

octomind run --model octohub:workhorse developer:general

एजेंट सोचता है कि वह एक ही प्रोवाइडर से बात कर रहा है। प्रॉक्सी के पीछे, workhorse आपके बेड़े में पंखे की तरह फैलता है, हर कॉल उस लागत और उस अपस्ट्रीम के साथ लॉग होती है जिसने जवाब दिया, और कॉन्करेंसी सीमा GPU मशीन को सीधा रखती है। एजेंट सरल रहता है; दृश्यता वहाँ रहती है जहाँ अनुरोध असल में तार पार करते हैं।

और यह कोई लैब सेटअप नहीं है। Octomind Cloud — हमारा मैनेज्ड एजेंट रनटाइम — हर ग्राहक एजेंट को प्रोडक्शन में OctoHub के माध्यम से चलाता है। कॉलें उद्देश्यों के साथ टैग होकर आती हैं (main, compression, supervisor-gate), auto मॉडल हर एक को सही टियर पर रूट करता है, और हर अनुरोध लॉग में लागत और जवाब देने वाले अपस्ट्रीम के साथ उतरता है। वही बाइनरी जिसे आप क्लोन कर सकते हैं, हमारे बेड़े के सामने खड़ी है।


ओपन सोर्स, Rust, Apache-2.0

OctoHub GitHub पर Apache-2.0 के तहत है। यह hyper पर आधारित एक अकेला Rust बाइनरी है — छोटा, तेज़, और निर्भरताओं में हल्का। डिफ़ॉल्ट रूप से SQLite, तो खड़ा करने को कुछ नहीं, और ज़रूरत पड़ने पर MySQL तथा PostgreSQL। कॉन्फ़िगरेशन एक TOML फ़ाइल है, साथ में मुट्ठी भर OCTOHUB_* एनवायरनमेंट ओवरराइड उन चीज़ों के लिए जिन्हें आप प्रति-डिप्लॉयमेंट बदलते हैं (OCTOHUB_DB_URL, OCTOHUB_LOG_FORMAT, OCTOHUB_METRICS_BIND)।

यह शुरुआती है — संस्करण 0.6.4, ईमानदार संख्या। यह वही करता है जो कहता है: एक प्रवेश द्वार, मॉडल अलियास, उद्देश्य-आधारित auto रूटिंग, failover और cooldown के साथ लोड बैलेंसिंग, प्रति-प्रोवाइडर कॉन्करेंसी और रेट लिमिट, मोडैलिटी चेक जो उन प्रोवाइडरों को छोड़ देते हैं जो आपकी इमेज या वीडियो नहीं संभाल सकते, मल्टी-टेनेंट कुंजियाँ, पूर्ण अनुरोध लॉगिंग, और एक Prometheus एंडपॉइंट। प्रोवाइडर सपोर्ट बढ़ती जा रही है — Google Studio 0.6.2 में आया, मौजूदा बीस से ज़्यादा के साथ। यह अभी स्ट्रीमिंग या वेटेड रूटिंग नहीं करता, और मैं आपको यह बताना पसंद करूँगा बजाय इसके कि आप इसे प्रोडक्शन में जानें।

अगर आप एक एप्लिकेशन के पीछे एक से ज़्यादा मॉडल चलाते हैं — और अगर आप एजेंट बना रहे हैं, तो चलाते हैं — तो OctoHub आपको वह एकल पैन देता है जिसके मौजूद होने को बाकी स्टैक चुपचाप मान लेता है। इसे क्लोन कीजिए, एक एजेंट को इस पर इंगित कीजिए, और एक रन को लागत समेत गुज़रते देखिए।

— Don

OctoHub Apache-2.0 के तहत ओपन सोर्स है, Muvon Un Limited द्वारा विकसित। इसे GitHub पर लीजिए — issues और pull requests का स्वागत है।