Messages and delivery
कमांड कतार
OpenClaw इनबाउंड ऑटो-रिप्लाई रन (सभी चैनल) को एक छोटी इन-प्रोसेस कतार के माध्यम से क्रमबद्ध करता है, ताकि एकाधिक एजेंट रन आपस में न टकराएँ और साथ ही सत्रों के बीच सुरक्षित समानांतरता बनी रहे।
क्यों
- ऑटो-रिप्लाई रन महँगे हो सकते हैं (LLM कॉल) और जब एकाधिक इनबाउंड संदेश लगभग एक साथ आते हैं, तो वे टकरा सकते हैं।
- क्रमबद्ध करने से साझा संसाधनों (सत्र फ़ाइलें, लॉग, CLI stdin) के लिए प्रतिस्पर्धा से बचा जाता है और अपस्ट्रीम दर सीमाएँ लागू होने की संभावना कम होती है।
यह कैसे काम करता है
- एक लेन-जागरूक FIFO कतार प्रत्येक लेन को कॉन्फ़िगर करने योग्य समवर्ती सीमा के साथ खाली करती है (बिना कॉन्फ़िगरेशन वाली लेन के लिए डिफ़ॉल्ट 1;
mainका डिफ़ॉल्ट 4 औरsubagentका 8 है)। runEmbeddedAgentसत्र कुंजी (लेनsession:<key>) के आधार पर कतारबद्ध करता है, ताकि प्रत्येक सत्र के लिए केवल एक सक्रिय रन की गारंटी रहे।- इसके बाद प्रत्येक सत्र रन को एक ग्लोबल लेन (डिफ़ॉल्ट रूप से
main) में कतारबद्ध किया जाता है, ताकि समग्र समानांतरताagents.defaults.maxConcurrentद्वारा सीमित रहे। - वर्बोज़ लॉगिंग सक्षम होने पर, कतारबद्ध रन शुरू होने से पहले ~2s से अधिक प्रतीक्षा करने पर एक छोटी सूचना उत्सर्जित करते हैं।
- कतारबद्ध होते ही टाइपिंग संकेतक अब भी तुरंत सक्रिय होते हैं (जब चैनल उनका समर्थन करता है), इसलिए रन के अपनी बारी की प्रतीक्षा करने के दौरान उपयोगकर्ता अनुभव अपरिवर्तित रहता है।
डिफ़ॉल्ट
सेट न होने पर, सभी इनबाउंड चैनल सतहें इनका उपयोग करती हैं:
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
उसी टर्न में स्टीयरिंग डिफ़ॉल्ट है। रन के बीच में आने वाला प्रॉम्प्ट सक्रिय रनटाइम में इंजेक्ट किया जाता है, बशर्ते रन स्टीयरिंग स्वीकार कर सके, इसलिए दूसरा सत्र रन शुरू नहीं होता। यदि सक्रिय रन स्टीयरिंग स्वीकार नहीं कर सकता, तो OpenClaw प्रॉम्प्ट शुरू करने से पहले सक्रिय रन के समाप्त होने की प्रतीक्षा करता है।
कतार मोड
/queue यह नियंत्रित करता है कि किसी सत्र में पहले से सक्रिय रन होने पर सामान्य इनबाउंड संदेश क्या करते हैं:
steer: संदेशों को सक्रिय रनटाइम में इंजेक्ट करें। OpenClaw सभी लंबित स्टीयरिंग संदेशों को वर्तमान असिस्टेंट टर्न के अपने टूल कॉल निष्पादित करने के बाद, अगले LLM कॉल से पहले डिलीवर करता है; Codex app-server को एक बैच किया हुआturn/steerप्राप्त होता है। यदि रन सक्रिय रूप से स्ट्रीम नहीं कर रहा है या स्टीयरिंग उपलब्ध नहीं है, तो OpenClaw प्रॉम्प्ट शुरू करने से पहले सक्रिय रन के समाप्त होने की प्रतीक्षा करता है।followup: स्टीयर न करें। वर्तमान रन समाप्त होने के बाद प्रत्येक संदेश को बाद के एजेंट टर्न के लिए कतारबद्ध करें।collect: स्टीयर न करें। शांत अवधि के बाद कतारबद्ध संदेशों को एकल फ़ॉलोअप टर्न में संयोजित करें। यदि संदेश अलग-अलग चैनल/थ्रेड को लक्षित करते हैं, तो रूटिंग बनाए रखने के लिए वे अलग-अलग खाली किए जाते हैं।interrupt: उस सत्र के सक्रिय रन को निरस्त करें, फिर नवीनतम संदेश चलाएँ।
रनटाइम-विशिष्ट समय और निर्भरता व्यवहार के लिए स्टीयरिंग कतार देखें। स्पष्ट /steer <message> कमांड के लिए स्टीयर करें देखें।
messages.queue के माध्यम से ग्लोबल रूप से या प्रति चैनल कॉन्फ़िगर करें:
{ messages: { queue: { mode: "steer", debounceMs: 500, cap: 20, drop: "summarize", byChannel: { discord: "collect" }, }, },}कतार विकल्प
विकल्प कतारबद्ध डिलीवरी पर लागू होते हैं। debounceMs, steer मोड में Codex स्टीयरिंग की शांत अवधि भी सेट करता है:
debounceMs: कतारबद्ध फ़ॉलोअप या कलेक्ट बैच खाली करने से पहले की शांत अवधि; Codexsteerमोड में, बैच किया हुआturn/steerभेजने से पहले की शांत अवधि। बिना इकाई वाली संख्याएँ मिलीसेकंड होती हैं;/queueविकल्पों द्वाराms,s,m,h, औरdइकाइयाँ स्वीकार की जाती हैं।cap: प्रति सत्र कतारबद्ध संदेशों की अधिकतम संख्या।1से कम मानों को अनदेखा किया जाता है।drop: "summarize"(डिफ़ॉल्ट): आवश्यकतानुसार सबसे पुरानी कतारबद्ध प्रविष्टियाँ हटाएँ, संक्षिप्त सारांश बनाए रखें और उन्हें सिंथेटिक फ़ॉलोअप प्रॉम्प्ट के रूप में इंजेक्ट करें।drop: "old": सारांश संरक्षित किए बिना, आवश्यकतानुसार सबसे पुरानी कतारबद्ध प्रविष्टियाँ हटाएँ।drop: "new": कतार पहले से भरी होने पर नवीनतम संदेश अस्वीकार करें।
डिफ़ॉल्ट: debounceMs: 500, cap: 20, drop: summarize।
स्टीयरिंग और स्ट्रीमिंग
जब चैनल स्ट्रीमिंग partial या block होती है, तो सक्रिय रन के रनटाइम सीमाओं तक पहुँचने के दौरान स्टीयरिंग कई छोटे दृश्यमान उत्तरों जैसा दिखाई दे सकता है:
partial: पूर्वावलोकन जल्दी अंतिम रूप ले सकता है, फिर स्टीयरिंग स्वीकार होने के बाद नया पूर्वावलोकन शुरू होता है।block: ड्राफ़्ट-आकार के ब्लॉक वही क्रमिक स्वरूप बना सकते हैं।- स्ट्रीमिंग के बिना, जब रनटाइम उसी टर्न में स्टीयरिंग स्वीकार नहीं कर सकता, तो सक्रिय रन के बाद स्टीयरिंग फ़ॉलोअप के रूप में फ़ॉलबैक करती है।
steer प्रगति पर चल रहे टूल निरस्त नहीं करता। जब नवीनतम संदेश को वर्तमान रन निरस्त करना चाहिए, तब /queue interrupt का उपयोग करें।
प्राथमिकता क्रम
मोड चयन के लिए, OpenClaw इस क्रम में समाधान करता है:
- इनलाइन या संग्रहीत प्रति-सत्र
/queueओवरराइड। messages.queue.byChannel.<channel>।messages.queue.mode।- डिफ़ॉल्ट
steer।
विकल्पों के लिए, इनलाइन या संग्रहीत /queue विकल्पों को कॉन्फ़िगरेशन पर प्राथमिकता मिलती है। फिर इसी क्रम में चैनल-विशिष्ट डीबाउंस (messages.queue.debounceMsByChannel), Plugin डीबाउंस डिफ़ॉल्ट, ग्लोबल messages.queue विकल्प और अंतर्निहित डिफ़ॉल्ट लागू किए जाते हैं। cap और drop ग्लोबल/सत्र विकल्प हैं, प्रति-चैनल कॉन्फ़िगरेशन कुंजियाँ नहीं।
प्रति-सत्र ओवरराइड
- वर्तमान सत्र के लिए कतार मोड संग्रहीत करने हेतु
/queue <steer|followup|collect|interrupt>को एक स्वतंत्र कमांड के रूप में भेजें। - विकल्पों को संयोजित किया जा सकता है:
/queue collect debounce:0.5s cap:25 drop:summarize /queue defaultया/queue resetसत्र ओवरराइड साफ़ करता है।
कतारबद्ध टर्न निरस्तीकरण
जब कोई प्रॉम्प्ट फ़ॉलोअप/कलेक्ट कतार में रहता है (उदाहरण के लिए, किसी अन्य टर्न के सक्रिय रहने के दौरान आने वाला TUI या
वेबचैट chat.send), तब Gateway उस क्लाइंट runId के लिए
Gateway-स्वामित्व वाली निरस्तीकरण पहचान तब तक बनाए रखता है, जब तक कतारबद्ध
सामग्री चल नहीं जाती या हटा नहीं दी जाती। यह पहचान ओवरफ़्लो सारांश में
समाहित सामग्री के साथ बनी रहती है।
- किसी विशिष्ट
runIdके साथchat.abort, उस टर्न के अब भी कतारबद्ध रहने के दौरान उसे निरस्त करता है, बशर्ते अनुरोधकर्ता अधिकृत हो (सक्रिय रन के समान स्वामित्व नियम)। - बिना
runIdवाले सत्र के लिएchat.abortपहले अधिकृत कतारबद्ध टर्न निरस्त करता है, फिर अधिकृत सक्रिय रन निरस्त करता है। यह क्रम कतार खाली होने पर कार्य को आधे-अधूरे रुके हुए सत्र में आगे बढ़ने से रोकता है। - प्रति-अनुरोधकर्ता जाँच के बिना पूरी सत्र कतार साफ़ करना बहु-स्वामी सत्रों के लिए स्टॉप पथ नहीं है।
- कतारबद्ध प्रतीक्षाएँ
sessions.listके लिए सक्रिय एजेंट रन के रूप में प्रक्षेपित नहीं होतीं और सक्रिय-रन टाइमआउट अर्थविज्ञान की स्वामी नहीं होतीं; केवल सक्रिय चरण इसका स्वामी होता है।
Gateway-समर्थित क्लाइंट (openclaw tui सहित) रन के बीच आने वाले प्रॉम्प्ट अग्रेषित करते हैं और
Gateway को कतार मोड लागू करने देते हैं। Esc//stop सत्र-स्कोप वाले निरस्तीकरण का उपयोग करता है,
ताकि खोए हुए स्थानीय हैंडल अब भी कतारबद्ध प्रॉम्प्ट को चलता हुआ न छोड़ दें।
openclaw chat और openclaw tui --local एम्बेडेड रनटाइम में वही चार मोड लागू करते हैं।
स्थानीय steer सक्रिय एम्बेडेड रन में तब इंजेक्ट करता है, जब वह रनटाइम
स्टीयरिंग स्वीकार करता है, अन्यथा वह फ़ॉलोअप बन जाता है; followup और
collect स्थानीय लंबित कार्य बने रहते हैं; interrupt नवीनतम संदेश शुरू करने से पहले
सक्रिय स्थानीय रन निरस्त करता है। स्पष्ट /steer <message> कमांड
स्थानीय-मोड कमांड नहीं है।
दायरा और गारंटियाँ
- यह गेटवे रिप्लाई पाइपलाइन का उपयोग करने वाले सभी इनबाउंड चैनलों (WhatsApp वेब, Telegram, Slack, Discord, Signal, iMessage, वेबचैट आदि) के ऑटो-रिप्लाई एजेंट रन पर लागू होता है।
- डिफ़ॉल्ट लेन (
main) इनबाउंड + मुख्य Heartbeat के लिए पूरी प्रक्रिया में साझा होती है; एकाधिक सत्रों को समानांतर चलने देने के लिएagents.defaults.maxConcurrentसेट करें। - अतिरिक्त लेन मौजूद हो सकती हैं (जैसे
cron,cron-nested,nested,subagent), ताकि बैकग्राउंड जॉब इनबाउंड उत्तरों को अवरुद्ध किए बिना समानांतर चल सकें। पृथक Cron एजेंट टर्न एकcronस्लॉट बनाए रखते हैं, जबकि उनका आंतरिक एजेंट निष्पादनcron-nestedका उपयोग करता है। साझा गैर-Cronnestedप्रवाह अपना लेन व्यवहार बनाए रखते हैं। इन अलग किए गए रन को बैकग्राउंड टास्क के रूप में ट्रैक किया जाता है। - प्रति-सत्र लेन गारंटी देती हैं कि एक समय में केवल एक एजेंट रन किसी दिए गए सत्र को प्रभावित करे।
- कोई बाहरी निर्भरता या बैकग्राउंड वर्कर थ्रेड नहीं; केवल TypeScript + प्रॉमिस।
समस्या निवारण
- यदि कमांड अटके हुए लगते हैं, तो वर्बोज़ लॉग सक्षम करें और यह पुष्टि करने के लिए "queued for ...ms" पंक्तियाँ खोजें कि कतार खाली हो रही है।
- जो Codex app-server रन किसी टर्न को स्वीकार करने के बाद प्रगति उत्सर्जित करना बंद कर देते हैं, उन्हें Codex अडैप्टर बाधित करता है, ताकि सक्रिय सत्र लेन बाहरी रन टाइमआउट की प्रतीक्षा करने के बजाय रिलीज़ हो सके।
- डायग्नोस्टिक्स सक्षम होने पर, वे सत्र जो बिना किसी देखे गए उत्तर, टूल, स्थिति, ब्लॉक या ACP प्रगति के अंतर्निहित चेतावनी सीमा से आगे
processingमें बने रहते हैं, उन्हें वर्तमान गतिविधि के आधार पर वर्गीकृत किया जाता है:- हाल की प्रगति वाला सक्रिय कार्य
session.long_runningके रूप में लॉग होता है। स्वामित्व वाली मौन मॉडल कॉल भी अंतर्निहित निरस्तीकरण सीमा तकsession.long_runningबनी रहती हैं, ताकि धीमे या गैर-स्ट्रीमिंग प्रदाताओं को बहुत जल्दी रुका हुआ न बताया जाए। - हाल की प्रगति के बिना सक्रिय कार्य
session.stalledके रूप में लॉग होता है; स्वामित्व वाली मॉडल कॉल, अवरुद्ध टूल कॉल और रुके हुए एम्बेडेड रन निरस्तीकरण सीमा पर या उसके बादsession.stalledमें बदल जाते हैं। स्वामी-विहीन पुरानी मॉडल/टूल गतिविधि को लंबे समय से चल रही गतिविधि के रूप में छिपाया नहीं जाता। session.stuckपुनर्प्राप्त करने योग्य पुराने सत्र बहीखाते के लिए आरक्षित है, जिसमें पुरानी स्वामी-विहीन मॉडल/टूल गतिविधि वाले निष्क्रिय कतारबद्ध सत्र शामिल हैं।session.stuckहमेशा ऐसी पुनर्प्राप्ति ट्रिगर करता है, जो प्रभावित सत्र लेन को रिलीज़ कर सकती है। निरस्तीकरण सीमा पार कर चुकाsession.stalledवर्गीकरण (अवरुद्ध टूल कॉल, रुकी हुई मॉडल कॉल या रुका हुआ एम्बेडेड रन) भी सक्रिय-निरस्तीकरण पुनर्प्राप्ति ट्रिगर कर सकता है, इसलिए केवलsession.stuckही नहीं, दोनों वर्गीकरण कतार को फिर से चला सकते हैं।- सत्र के अपरिवर्तित रहने के दौरान बार-बार आने वाली
session.stuckऔरsession.long_runningचेतावनी लॉग पंक्तियाँ घातांकीय रूप से पीछे हटती हैं; उस बैकऑफ़ के बावजूद प्रत्येक Heartbeat टिक पर पुनर्प्राप्ति प्रयास चलते रहते हैं।
- हाल की प्रगति वाला सक्रिय कार्य