Messages and delivery
قائمة انتظار الأوامر
نُسلسل عمليات الرد التلقائي الواردة (كل القنوات) عبر طابور صغير داخل العملية لمنع تصادم عدة عمليات تشغيل للوكيل، مع استمرار السماح بالتوازي الآمن عبر الجلسات.
لماذا
- قد تكون عمليات الرد التلقائي مكلفة (استدعاءات LLM) وقد تتصادم عند وصول عدة رسائل واردة في وقت متقارب.
- يمنع التسلسل التنافس على الموارد المشتركة (ملفات الجلسات، السجلات، إدخال CLI القياسي) ويقلل احتمال الوصول إلى حدود المعدل لدى الجهات العليا.
آلية العمل
- طابور FIFO واعٍ بالمسارات يفرغ كل مسار بحد تزامن قابل للضبط (الافتراضي 1 للمسارات غير المضبوطة؛ الافتراضي لـ main هو 4، ولـ subagent هو 8).
- يضيف
runEmbeddedAgentإلى الطابور حسب مفتاح الجلسة (المسارsession:<key>) لضمان وجود عملية تشغيل نشطة واحدة فقط لكل جلسة. - تُضاف كل عملية تشغيل جلسة بعد ذلك إلى مسار عام (
mainافتراضياً) بحيث يكون التوازي الإجمالي محدوداً بواسطةagents.defaults.maxConcurrent. - عند تفعيل التسجيل التفصيلي، تصدر عمليات التشغيل الموضوعة في الطابور إشعاراً قصيراً إذا انتظرت أكثر من نحو ثانيتين قبل البدء.
- ما زالت مؤشرات الكتابة تعمل فوراً عند الإضافة إلى الطابور (عندما تدعمها القناة)، لذلك لا تتغير تجربة المستخدم أثناء انتظار دورنا.
الإعدادات الافتراضية
عند عدم ضبطها، تستخدم كل أسطح القنوات الواردة:
mode: "steer"debounceMs: 500cap: 20drop: "summarize"
التوجيه في الدور نفسه هو الافتراضي. تُحقن المطالبة التي تصل أثناء تشغيل جارٍ داخل وقت التشغيل النشط عندما يستطيع التشغيل قبول التوجيه، لذلك لا تبدأ عملية تشغيل جلسة ثانية. إذا لم يستطع التشغيل النشط قبول التوجيه، ينتظر OpenClaw انتهاء التشغيل النشط قبل بدء المطالبة.
أوضاع الطابور
يتحكم /queue بما تفعله الرسائل الواردة العادية عندما تكون للجلسة عملية تشغيل
نشطة بالفعل:
steer: يحقن الرسائل في وقت التشغيل النشط. يسلّم OpenClaw كل رسائل التوجيه المعلقة بعد انتهاء دور المساعد الحالي من تنفيذ استدعاءات أدواته، وقبل استدعاء LLM التالي؛ يتلقى خادم تطبيق Codex دفعة واحدة منturn/steer. إذا لم يكن التشغيل يبث بنشاط أو لم يكن التوجيه متاحاً، ينتظر OpenClaw حتى ينتهي التشغيل النشط قبل بدء المطالبة.followup: لا يوجّه. يضيف كل رسالة إلى الطابور لدور وكيل لاحق بعد انتهاء التشغيل الحالي.collect: لا يوجّه. يدمج الرسائل الموضوعة في الطابور في دور متابعة واحد بعد نافذة الهدوء. إذا استهدفت الرسائل قنوات/سلاسل مختلفة، تُفرغ كل رسالة على حدة للحفاظ على التوجيه.interrupt: يجهض التشغيل النشط لتلك الجلسة، ثم يشغل أحدث رسالة.
لسلوك التوقيت والتبعيات الخاص بوقت التشغيل، راجع
طابور التوجيه. للأمر الصريح /steer <message>،
راجع توجيه.
اضبطه عاماً أو لكل قناة عبر messages.queue:
{ messages: { queue: { mode: "steer", debounceMs: 500, cap: 20, drop: "summarize", byChannel: { discord: "collect" }, }, },}خيارات الطابور
تنطبق الخيارات على التسليم الموضوع في الطابور. يضبط debounceMs أيضاً نافذة الهدوء
لتوجيه Codex في وضع steer:
debounceMs: نافذة الهدوء قبل تفريغ المتابعات الموضوعة في الطابور أو دفعات الجمع؛ في وضعsteerالخاص بـ Codex، نافذة الهدوء قبل إرسال دفعة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تجاوز الجلسة.
النطاق والضمانات
- ينطبق على عمليات تشغيل وكيل الرد التلقائي عبر كل القنوات الواردة التي تستخدم مسار رد Gateway (ويب WhatsApp، وTelegram، وSlack، وDiscord، وSignal، وiMessage، ودردشة الويب، وما إلى ذلك).
- المسار الافتراضي (
main) عام على مستوى العملية للوارد + Heartbeat الرئيسية؛ اضبطagents.defaults.maxConcurrentللسماح بعدة جلسات بالتوازي. - قد توجد مسارات إضافية (مثل
cron، وcron-nested، وnested، وsubagent) بحيث يمكن للمهام الخلفية أن تعمل بالتوازي من دون حظر الردود الواردة. تحتفظ أدوار وكيل Cron المعزولة بخانةcronبينما يستخدم تنفيذ الوكيل الداخليcron-nested؛ وكلاهما يستخدمcron.maxConcurrentRuns. تحافظ تدفقاتnestedالمشتركة غير Cron على سلوك المسار الخاص بها. تُتبع عمليات التشغيل المنفصلة هذه كـ مهام خلفية. - تضمن مسارات كل جلسة أن عملية تشغيل وكيل واحدة فقط تلمس جلسة معينة في كل مرة.
- لا توجد تبعيات خارجية أو خيوط عامل خلفية؛ TypeScript خالص + وعود.
استكشاف الأخطاء وإصلاحها
- إذا بدت الأوامر عالقة، فعّل السجلات التفصيلية وابحث عن أسطر "queued for ...ms" لتأكيد أن الطابور يُفرغ.
- إذا كنت تحتاج إلى عمق الطابور، فعّل السجلات التفصيلية وراقب أسطر توقيت الطابور.
- عمليات تشغيل خادم تطبيق Codex التي تقبل دوراً ثم تتوقف عن إصدار تقدم تُقاطع بواسطة محول Codex لكي يتحرر مسار الجلسة النشط بدلاً من انتظار انتهاء مهلة التشغيل الخارجية.
- عند تفعيل التشخيصات، تُصنف الجلسات التي تبقى في
processingبعدdiagnostics.stuckSessionWarnMsمن دون أي رد أو أداة أو حالة أو كتلة أو تقدم ACP مرصود حسب النشاط الحالي. يُسجل العمل النشط كـsession.long_running؛ كما تبقى استدعاءات النموذج الصامتة المملوكةsession.long_runningحتىdiagnostics.stuckSessionAbortMsكي لا يُبلّغ عن الموفرين البطيئين أو غير الباثين كمتوقفين مبكراً جداً. يُسجل العمل النشط الذي لا يملك تقدماً حديثاً كـsession.stalled؛ وتتحول استدعاءات النموذج المملوكة إلىsession.stalledعند عتبة الإجهاض أو بعدها، ولا يُخفى نشاط النموذج/الأداة القديم غير المملوك باعتباره طويل التشغيل. يُحجزsession.stuckلحفظ سجلات الجلسات القديمة القابلة للاسترداد، بما في ذلك الجلسات الخاملة الموضوعة في الطابور ذات نشاط نموذج/أداة قديم غير مملوك، وهذا المسار وحده يمكنه تحرير مسار الجلسة المتأثر لكي يُفرغ العمل الموضوع في الطابور. تتراجع تشخيصاتsession.stuckالمتكررة بينما تبقى الجلسة دون تغيير.