التدفق والتجزئة
يحتوي OpenClaw على طبقتين منفصلتين للتدفق:
- تدفق الكتل (القنوات): إصدار كتل مكتملة أثناء كتابة المساعد. هذه رسائل قناة عادية (وليست تغييرات جزئية للرموز).
- تدفق المعاينة (Telegram/Discord/Slack): تحديث رسالة معاينة مؤقتة أثناء التوليد.
لا يوجد تدفق حقيقي للتغييرات الجزئية للرموز إلى رسائل القناة اليوم. تدفق المعاينة يعتمد على الرسائل (إرسال + تعديلات/إلحاق).
تدفق الكتل (رسائل القناة)
يقوم تدفق الكتل بإرسال مخرجات المساعد في أجزاء كبيرة بمجرد توفرها.
Model output
└─ text_delta/events
├─ (blockStreamingBreak=text_end)
│ └─ chunker emits blocks as buffer grows
└─ (blockStreamingBreak=message_end)
└─ chunker flushes at message_end
└─ channel send (block replies)
وسائل الإيضاح:
text_delta/events: أحداث دفق النموذج (قد تكون متفرقة للنماذج غير المتدفقة).chunker:EmbeddedBlockChunkerيطبق حدود الحد الأدنى/الأقصى + تفضيل الفصل.channel send: الرسائل الصادرة الفعلية (ردود الكتل).
عناصر التحكم:
agents.defaults.blockStreamingDefault:"on"/"off"(الإعداد الافتراضي off).- تجاوزات القناة:
*.blockStreaming(والمتغيرات الخاصة بكل حساب) لإجبار"on"/"off"لكل قناة. agents.defaults.blockStreamingBreak:"text_end"أو"message_end".agents.defaults.blockStreamingChunk:{ minChars, maxChars, breakPreference? }.agents.defaults.blockStreamingCoalesce:{ minChars?, maxChars?, idleMs? }(دمج الكتل المتدفقة قبل الإرسال).- الحد الأقصى الثابت للقناة:
*.textChunkLimit(مثال:channels.whatsapp.textChunkLimit). - وضع تجزئة القناة:
*.chunkMode(lengthافتراضي،newlineيقسم على الأسطر الفارغة (حدود الفقرات) قبل التجزئة بالطول). - الحد الأقصى المرن لـ Discord:
channels.discord.maxLinesPerMessage(الافتراضي 17) يقسم الردود الطويلة لتجنب القص في واجهة المستخدم.
دلالات الحدود:
text_end: دفق الكتل بمجرد إصدارها من قبل المُجزئ؛ تفريغ عند كلtext_end.message_end: الانتظار حتى تنتهي رسالة المساعد، ثم تفريغ النص المخزن مؤقتًا.
لا يزال message_end يستخدم المُجزئ إذا تجاوز النص المخزن maxChars، لذا يمكنه إصدار أجزاء متعددة في النهاية.
خوارزمية التجزئة (حدود منخفضة/عالية)
يتم تنفيذ تجزئة الكتل بواسطة EmbeddedBlockChunker:
- الحد الأدنى: عدم الإصدار حتى يصبح المخزن المؤقت >=
minChars(ما لم يُجبر). - الحد الأقصى: تفضيل الانقسام قبل
maxChars؛ إذا أُجبر، الانقسام عندmaxChars. - تفضيل الفصل:
paragraph→newline→sentence→whitespace→ انقسام صارم. - أسوار الكود: عدم الانقسام داخل الأسوار أبدًا؛ عند الإجبار عند
maxChars، إغلاق + إعادة فتح السور للحفاظ على صلاحية Markdown.
يتم تحديد maxChars بحد textChunkLimit للقناة، لذا لا يمكنك تجاوز الحدود القصوى لكل قناة.
الدمج (دمج الكتل المتدفقة)
عند تمكين تدفق الكتل، يمكن لـ OpenClaw دمج أجزاء الكتل المتتالية قبل إرسالها. هذا يقلل من "الرسائل المزعجة ذات السطر الواحد" مع توفير مخرجات تدريجية.
- ينتظر الدمج فجوات الخمول (
idleMs) قبل التفريغ. - يتم تحديد سعة المخازن المؤقتة بـ
maxCharsوسيتم تفريغها إذا تجاوزتها. - يمنع
minCharsإرسال الأجزاء الصغيرة جدًا حتى يتراكم نص كافٍ (دائمًا ما يرسل التفريغ النهائي النص المتبقي). - يُشتق الموصل من
blockStreamingChunk.breakPreference(paragraph→\n\n,newline→\n,sentence→ مسافة). - تتوفر تجاوزات القناة عبر
*.blockStreamingCoalesce(بما في ذلك إعدادات كل حساب). - يتم رفع الحد الأدنى الافتراضي للدمج
minCharsإلى 1500 لـ Signal/Slack/Discord ما لم يتم تجاوزه.
وتيرة شبيهة بالإنسان بين الكتل
عند تمكين تدفق الكتل، يمكنك إضافة توقف عشوائي بين ردود الكتل (بعد الكتلة الأولى). هذا يجعل الردود متعددة الفقاعات تبدو أكثر طبيعية.
- الإعداد:
agents.defaults.humanDelay(تجاوز لكل وكيل عبرagents.list[].humanDelay). - الأوضاع:
off(افتراضي)،natural(800–2500ms)،custom(minMs/maxMs). - ينطبق فقط على ردود الكتل، وليس الردود النهائية أو ملخصات الأدوات.
"تدفق الأجزاء أو كل شيء"
هذا يُقابل:
- تدفق الأجزاء:
blockStreamingDefault: "on"+blockStreamingBreak: "text_end"(الإصدار أثناء التقدم). تحتاج القنوات غير Telegram أيضًا إلى*.blockStreaming: true. - تدفق كل شيء في النهاية:
blockStreamingBreak: "message_end"(تفريغ مرة واحدة، ربما أجزاء متعددة إذا كانت طويلة جدًا). - لا تدفق للكتل:
blockStreamingDefault: "off"(الرد النهائي فقط).
ملاحظة القناة: تدفق الكتل معطل ما لم يتم تعيين *.blockStreaming صراحةً إلى true. يمكن للقنوات أن تدفق معاينة حية (channels.<channel>.streaming) بدون ردود كتل. تذكير بموقع الإعداد: الإعدادات الافتراضية blockStreaming* موجودة تحت agents.defaults، وليس الإعداد الجذري.
أوضاع تدفق المعاينة
المفتاح الأساسي: channels.<channel>.streaming الأوضاع:
off: تعطيل تدفق المعاينة.partial: معاينة واحدة يتم استبدالها بأحدث نص.block: تحديثات المعاينة في خطوات مجزأة/مُلحقة.progress: معاينة للتقدم/الحالة أثناء التوليد، الإجابة النهائية عند الانتهاء.
تعيين القناة
| القناة | off | partial | block | progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | تُعيّن إلى partial |
| Discord | ✅ | ✅ | ✅ | تُعيّن إلى partial |
| Slack | ✅ | ✅ | ✅ | ✅ |
خاص بـ Slack فقط:
channels.slack.nativeStreamingيبدل واجهة برمجة تطبيقات التدفق الأصلية لـ Slack عندstreaming=partial(الافتراضي:true).
ترحيل المفاتيح القديمة:
- Telegram:
streamMode+ القيمة المنطقيةstreamingتنتقل تلقائيًا إلى تعدادstreaming. - Discord:
streamMode+ القيمة المنطقيةstreamingتنتقل تلقائيًا إلى تعدادstreaming. - Slack:
streamModeتنتقل تلقائيًا إلى تعدادstreaming؛ القيمة المنطقيةstreamingتنتقل تلقائيًا إلىnativeStreaming.
سلوك وقت التشغيل
Telegram:
- يستخدم Bot API
sendMessageDraftفي الرسائل المباشرة عند التوفر، وsendMessage+editMessageTextلتحديثات معاينة المجموعة/الموضوع. - يتم تخطي تدفق المعاينة عندما يتم تمكين تدفق كتل Telegram صراحةً (لتجنب التدفق المزدوج).
- يمكن لـ
/reasoning streamكتابة المنطق في المعاينة.
Discord:
- يستخدم إرسال + تعديل رسائل المعاينة.
- وضع
blockيستخدم تجزئة المسودة (draftChunk). - يتم تخطي تدفق المعاينة عندما يتم تمكين تدفق كتل Discord صراحةً.
Slack:
- يمكن لـ
partialاستخدام التدفق الأصلي لـ Slack (chat.startStream/append/stop) عند التوفر. - يستخدم
blockمعاينات مسودة على نمط الإلحاق. - يستخدم
progressنص معاينة للحالة، ثم الإجابة النهائية.