Messages and delivery
جریانسازی و قطعهبندی
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"(پیشفرض خاموش).- بازنویسیهای کانال:
*.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) پاسخهای بلند را جدا میکند تا از بریدهشدن UI جلوگیری شود.
معنای مرزها:
text_end: بهمحض اینکه قطعهکن بلوک تولید کند، بلوکها را استریم میکند؛ در هرtext_endتخلیه میکند.message_end: تا پایان پیام دستیار صبر میکند، سپس خروجی بافرشده را تخلیه میکند.
message_end همچنان اگر متن بافرشده از maxChars بیشتر باشد از قطعهکن استفاده میکند، بنابراین میتواند در پایان چندین قطعه منتشر کند.
تحویل رسانه با استریم بلوکی
دستورهای MEDIA: فرادادهٔ عادی تحویل هستند. وقتی استریم بلوکی یک بلوک رسانهای را زودتر ارسال کند، OpenClaw آن تحویل را برای نوبت به خاطر میسپارد. اگر بار نهایی دستیار همان نشانی رسانه را تکرار کند، تحویل نهایی بهجای ارسال دوبارهٔ پیوست، رسانهٔ تکراری را حذف میکند.
بارهای نهایی کاملاً تکراری سرکوب میشوند. اگر بار نهایی متن متمایزی پیرامون رسانهای اضافه کند که قبلاً استریم شده است، OpenClaw همچنان متن جدید را میفرستد و رسانه را تکتحویلی نگه میدارد. این کار از تکرار یادداشتهای صوتی یا فایلها در کانالهایی مانند Telegram جلوگیری میکند، وقتی یک عامل هنگام استریم MEDIA: منتشر میکند و ارائهدهنده نیز آن را در پاسخ کاملشده میگنجاند.
الگوریتم قطعهکردن (کرانهای پایین/بالا)
قطعهکردن بلوک با 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برای همتجمیعی، برای Signal/Slack/Discord به 1500 افزایش داده میشود مگر اینکه بازنویسی شده باشد.
آهنگ انسانی بین بلوکها
وقتی استریم بلوکی فعال باشد، میتوانید بین پاسخهای بلوکی (پس از بلوک اول) یک مکث تصادفیشده اضافه کنید. این کار پاسخهای چندحبابی را طبیعیتر میکند.
- پیکربندی:
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: پیشنمایش پیشرفت/وضعیت هنگام تولید، پاسخ نهایی هنگام تکمیل.
streaming.mode: "block" یک حالت استریم پیشنمایش برای کانالهای قابلویرایش
مانند Discord و Telegram است. این حالت تحویل بلوکی کانال را در آنجا فعال نمیکند.
وقتی پاسخهای بلوکی عادی میخواهید، از streaming.block.enabled یا کلید قدیمی کانال blockStreaming استفاده کنید. Microsoft Teams استثناست: انتقال بلوکی پیشنویس پیشنمایش ندارد، بنابراین streaming.mode: "block" بهجای استریم بومی جزئی/پیشرفت، به تحویل بلوکی Teams نگاشت میشود.
نگاشت کانال
| کانال | off |
partial |
block |
progress |
|---|---|---|---|---|
| Telegram | ✅ | ✅ | ✅ | پیشنویس پیشرفت قابلویرایش |
| Discord | ✅ | ✅ | ✅ | پیشنویس پیشرفت قابلویرایش |
| Slack | ✅ | ✅ | ✅ | ✅ |
| Mattermost | ✅ | ✅ | ✅ | ✅ |
| MS Teams | ✅ | ✅ | ✅ | استریم پیشرفت بومی |
فقط Slack:
channels.slack.streaming.nativeTransportفراخوانیهای API استریم بومی Slack را وقتیchannels.slack.streaming.mode="partial"باشد تغییر وضعیت میدهد (پیشفرض:true).- استریم بومی Slack و وضعیت رشتهٔ دستیار Slack به هدف رشتهٔ پاسخ نیاز دارند. پیامهای مستقیم سطح بالا آن پیشنمایش سبک رشته را نشان نمیدهند، اما همچنان میتوانند از پستها و ویرایشهای پیشنمایش پیشنویس Slack استفاده کنند.
مهاجرت کلید قدیمی:
- Telegram: مقدارهای قدیمی
streamModeو مقدارهای عددی/بولیstreamingشناسایی میشوند و مسیرهای سازگاری doctor/config آنها را بهstreaming.modeمهاجرت میکنند. - Discord:
streamMode+ مقدار بولیstreamingهمچنان نامهای مستعار زمان اجرا برای enumstreamingهستند؛ برای بازنویسی پیکربندی ذخیرهشده،openclaw doctor --fixرا اجرا کنید. - Slack:
streamModeهمچنان نام مستعار زمان اجرا برایstreaming.modeاست؛ مقدار بولیstreamingهمچنان نام مستعار زمان اجرا برایstreaming.modeبههمراهstreaming.nativeTransportاست؛nativeStreamingقدیمی همچنان نام مستعار زمان اجرا برایstreaming.nativeTransportاست. برای بازنویسی پیکربندی ذخیرهشده،openclaw doctor --fixرا اجرا کنید.
رفتار زمان اجرا
Telegram:
- از بهروزرسانیهای پیشنمایش
sendMessage+editMessageTextدر پیامهای مستقیم و گروهها/موضوعها استفاده میکند. - متن نهایی، پیشنمایش فعال را درجا ویرایش میکند؛ نهاییهای طولانی از همان پیام برای قطعهٔ اول استفاده میکنند و فقط قطعههای باقیمانده را میفرستند.
- حالت
progressپیشرفت ابزار را در یک پیشنویس وضعیت قابلویرایش نگه میدارد، آن پیشنویس را هنگام تکمیل پاک میکند، و پاسخ نهایی را از مسیر تحویل عادی میفرستد. - اگر ویرایش نهایی پیش از تأیید متن کاملشده شکست بخورد، OpenClaw از تحویل نهایی عادی استفاده میکند و پیشنمایش کهنه را پاکسازی میکند.
- وقتی استریم بلوکی Telegram صراحتاً فعال باشد، استریم پیشنمایش رد میشود (برای جلوگیری از استریم دوگانه).
/reasoning streamمیتواند استدلال را در پیشنمایشی گذرا بنویسد که پس از تحویل نهایی حذف میشود.
Discord:
- از پیامهای پیشنمایش با ارسال + ویرایش استفاده میکند.
- حالت
blockاز قطعهکردن پیشنویس (draftChunk) استفاده میکند. - وقتی استریم بلوکی Discord صراحتاً فعال باشد، استریم پیشنمایش رد میشود.
- رسانهٔ نهایی، خطا، و بارهای پاسخ صریح، پیشنمایشهای در انتظار را بدون تخلیهٔ پیشنویس جدید لغو میکنند، سپس از تحویل عادی استفاده میکنند.
Slack:
partialمیتواند وقتی در دسترس باشد از استریم بومی Slack (chat.startStream/append/stop) استفاده کند.blockاز پیشنمایشهای پیشنویس به سبک افزودن استفاده میکند.progressاز متن پیشنمایش وضعیت و سپس پاسخ نهایی استفاده میکند.- پیامهای مستقیم سطح بالا بدون رشتهٔ پاسخ، بهجای استریم بومی Slack از پستها و ویرایشهای پیشنمایش پیشنویس استفاده میکنند.
- استریم بومی و پیشنمایش پیشنویس، پاسخهای بلوکی را برای آن نوبت سرکوب میکنند، بنابراین یک پاسخ Slack فقط از یک مسیر تحویل استریم میشود.
- بارهای رسانه/خطای نهایی و نهاییهای پیشرفت، پیامهای پیشنویس دورریختنی ایجاد نمیکنند؛ فقط نهاییهای متن/بلوک که میتوانند پیشنمایش را ویرایش کنند، متن پیشنویس در انتظار را تخلیه میکنند.
Mattermost:
- تفکر، فعالیت ابزار، و متن پاسخ جزئی را در یک پست پیشنمایش پیشنویس واحد استریم میکند که وقتی ارسال پاسخ نهایی ایمن باشد درجا نهایی میشود.
- اگر پست پیشنمایش حذف شده باشد یا در زمان نهاییسازی به هر دلیل در دسترس نباشد، به ارسال یک پست نهایی تازه برمیگردد.
- بارهای رسانه/خطای نهایی، بهجای تخلیهٔ یک پست پیشنمایش موقت، پیش از تحویل عادی بهروزرسانیهای پیشنمایش در انتظار را لغو میکنند.
Matrix:
- وقتی متن نهایی بتواند از رویداد پیشنمایش دوباره استفاده کند، پیشنمایشهای پیشنویس درجا نهایی میشوند.
- نهاییهای فقطرسانه، خطا، و عدمتطابق هدف پاسخ، پیش از تحویل عادی بهروزرسانیهای پیشنمایش در انتظار را لغو میکنند؛ یک پیشنمایش کهنهٔ از پیش قابلمشاهده حذف محتوایی میشود.
بهروزرسانیهای پیشنمایش پیشرفت ابزار
استریم پیشنمایش همچنین میتواند بهروزرسانیهای پیشرفت ابزار را شامل شود - خطهای کوتاه وضعیت مانند «در حال جستوجو در وب»، «در حال خواندن فایل»، یا «در حال فراخوانی ابزار» - که هنگام اجرای ابزارها و پیش از پاسخ نهایی، در همان پیام پیشنمایش ظاهر میشوند. این کار نوبتهای چندمرحلهای ابزار را از نظر بصری زنده نگه میدارد، بهجای اینکه بین نخستین پیشنمایش تفکر و پاسخ نهایی ساکت بمانند.
سطوح پشتیبانیشده:
- Discord، Slack، Telegram و Matrix وقتی جریاندهی پیشنمایش فعال باشد، بهطور پیشفرض پیشرفت ابزار را در ویرایش پیشنمایش زنده جریاندهی میکنند. Microsoft Teams در چتهای شخصی از جریان پیشرفت بومی خود استفاده میکند.
- Telegram از
v2026.4.22با بهروزرسانیهای پیشنمایش پیشرفت ابزارِ فعال عرضه شده است؛ فعال نگه داشتن آنها رفتار منتشرشده را حفظ میکند. - Mattermost از قبل فعالیت ابزار را در تنها پست پیشنمایش پیشنویس خود ادغام میکند (بالا را ببینید).
- ویرایشهای پیشرفت ابزار از حالت فعال جریاندهی پیشنمایش پیروی میکنند؛ وقتی جریاندهی پیشنمایش
offباشد یا وقتی جریاندهی بلوکی کنترل پیام را به دست گرفته باشد، از آنها صرفنظر میشود. در Telegram،streaming.mode: "off"فقط نهایی است: گفتوگوی عمومی پیشرفت نیز بهجای تحویل بهصورت پیامهای وضعیت مستقل، سرکوب میشود، در حالی که درخواستهای تأیید، payloadهای رسانهای و خطاها همچنان بهصورت عادی مسیریابی میشوند. - برای نگه داشتن جریاندهی پیشنمایش اما پنهان کردن خطوط پیشرفت ابزار، برای آن کانال
streaming.preview.toolProgressرا رویfalseتنظیم کنید. برای قابل مشاهده نگه داشتن خطوط پیشرفت ابزار در حالی که متن فرمان/اجرا پنهان است،streaming.preview.commandTextرا روی"status"یاstreaming.progress.commandTextرا روی"status"تنظیم کنید؛ مقدار پیشفرض برای حفظ رفتار منتشرشده"raw"است. این سیاست میان کانالهای پیشنویس/پیشرفت که از نمایشدهنده فشرده پیشرفت OpenClaw استفاده میکنند مشترک است، از جمله Discord، Matrix، Microsoft Teams، Mattermost، پیشنمایشهای پیشنویس Slack، و Telegram. برای غیرفعال کردن کامل ویرایشهای پیشنمایش،streaming.modeرا رویoffتنظیم کنید. - پاسخهای نقلقول انتخابشده در Telegram یک استثنا هستند: وقتی
replyToModeبرابر"off"نباشد و متن نقلقول انتخابشده وجود داشته باشد، OpenClaw جریان پیشنمایش پاسخ را برای آن نوبت رد میکند تا خطوط پیشنمایش پیشرفت ابزار نتوانند رندر شوند. پاسخهای پیام فعلی بدون متن نقلقول انتخابشده همچنان جریاندهی پیشنمایش را نگه میدارند. برای جزئیات، مستندات کانال Telegram را ببینید.
خطوط پیشرفت را قابل مشاهده نگه دارید اما متن خام فرمان/اجرا را پنهان کنید:
{
"channels": {
"telegram": {
"streaming": {
"mode": "partial",
"preview": {
"toolProgress": true,
"commandText": "status"
}
}
}
}
}
از همین شکل زیر کلید یک کانال پیشرفت فشرده دیگر استفاده کنید، برای مثال channels.discord، channels.matrix، channels.msteams، channels.mattermost، یا پیشنمایشهای پیشنویس Slack. برای حالت پیشنویس پیشرفت، همین سیاست را زیر streaming.progress قرار دهید:
{
"channels": {
"telegram": {
"streaming": {
"mode": "progress",
"progress": {
"toolProgress": true,
"commandText": "status"
}
}
}
}
}
مرتبط
- بازآرایی چرخه عمر پیام - طراحی هدف برای پیشنمایش، ویرایش، جریاندهی و نهاییسازی مشترک
- پیشنویسهای پیشرفت - پیامهای کار در جریانِ قابل مشاهده که در طول نوبتهای طولانی بهروزرسانی میشوند
- پیامها - چرخه عمر و تحویل پیام
- تلاش مجدد - رفتار تلاش مجدد هنگام شکست تحویل
- کانالها - پشتیبانی جریاندهی به تفکیک کانال