إدارة الجلسات
تعامل OpenClaw مع جلسة محادثة مباشرة واحدة لكل وكيل على أنها الأساسية. تنهار المحادثات المباشرة إلى agent:<agentId>:<mainKey> (الافتراضي main)، بينما تحصل محادثات المجموعة/القناة على مفاتيح خاصة بها. يتم احترام session.mainKey. استخدم session.dmScope للتحكم في كيفية تجميع الرسائل المباشرة:
main(الافتراضي): جميع الرسائل المباشرة تشارك الجلسة الرئيسية لضمان الاستمرارية.per-peer: عزل حسب هوية المرسل عبر القنوات.per-channel-peer: عزل حسب القناة + المرسل (موصى به للصناديق الواردة متعددة المستخدمين).per-account-channel-peer: عزل حسب الحساب + القناة + المرسل (موصى به للصناديق الواردة متعددة الحسابات). استخدمsession.identityLinksلتعيين هويات الأقران ذات البادئة الخاصة بالمزود إلى هوية قياسية بحيث يشارك نفس الشخص جلسة رسائل مباشرة عبر القنوات عند استخدامper-peer، أوper-channel-peer، أوper-account-channel-peer.
وضع الرسائل المباشرة الآمن (موصى به للإعدادات متعددة المستخدمين)
تحذير أمني: إذا كان وكيلك يمكنه استقبال رسائل مباشرة من عدة أشخاص، فيجب أن تفكر جدياً في تمكين وضع الرسائل المباشرة الآمن. بدونه، يشارك جميع المستخدمين نفس سياق المحادثة، مما قد يؤدي إلى تسريب معلومات خاصة بين المستخدمين.
مثال على المشكلة مع الإعدادات الافتراضية:
- أليس (
<SENDER_A>) ترسل رسالة إلى وكيلك حول موضوع خاص (على سبيل المثال، موعد طبي) - بوب (
<SENDER_B>) يرسل رسالة إلى وكيلك يسأل فيها "عماذا كنا نتحدث؟" - لأن كلا الرسالتين المباشرتين تشاركان نفس الجلسة، قد يجيب النموذج بوب باستخدام السياق السابق لأليس.
الحل: اضبط dmScope لعزل الجلسات لكل مستخدم:
// ~/.openclaw/openclaw.json
{
session: {
// وضع الرسائل المباشرة الآمن: عزل سياق الرسائل المباشرة لكل قناة + مرسل.
dmScope: "per-channel-peer",
},
}
متى يتم تمكين هذا:
- لديك موافقات إقران لأكثر من مرسل واحد
- تستخدم قائمة السماح للرسائل المباشرة تحتوي على عدة إدخالات
- تضبط
dmPolicy: "open" - يمكن لعدة أرقام هواتف أو حسابات مراسلة وكيلك
ملاحظات:
- الافتراضي هو
dmScope: "main"للاستمرارية (جميع الرسائل المباشرة تشارك الجلسة الرئيسية). هذا مناسب للإعدادات ذات المستخدم الواحد. - عملية الإعداد المحلية لـ CLI تكتب
session.dmScope: "per-channel-peer"افتراضياً عندما لا تكون محددة (يتم الحفاظ على القيم الصريحة الموجودة). - للصناديق الواردة متعددة الحسابات على نفس القناة، يُفضل استخدام
per-account-channel-peer. - إذا اتصل بك نفس الشخص على قنوات متعددة، استخدم
session.identityLinksلدمج جلسات الرسائل المباشرة الخاصة به في هوية قياسية واحدة. - يمكنك التحقق من إعدادات الرسائل المباشرة الخاصة بك باستخدام
openclaw security audit(انظر الأمان).
البوابة هي مصدر الحقيقة
جميع حالة الجلسة مملوكة للبوابة (الـ "OpenClaw الرئيسي"). يجب على عملاء واجهة المستخدم (تطبيق macOS، وWebChat، إلخ.) الاستعلام من البوابة للحصول على قوائم الجلسات وأعداد الرموز بدلاً من قراءة الملفات المحلية.
- في الوضع البعيد، مخزن الجلسات الذي تهتم به موجود على مضيف البوابة البعيد، وليس على جهاز Mac الخاص بك.
- أعداد الرموز المعروضة في واجهات المستخدم تأتي من حقول المخزن في البوابة (
inputTokens,outputTokens,totalTokens,contextTokens). لا يقوم العملاء بتحليل نصوص JSONL "لتصحيح" الإجماليات.
أين توجد الحالة
- على مضيف البوابة:
- ملف المخزن:
~/.openclaw/agents/<agentId>/sessions/sessions.json(لكل وكيل).
- ملف المخزن:
- النصوص:
~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl(جلسات مواضيع Telegram تستخدم.../<SessionId>-topic-<threadId>.jsonl). - المخزن عبارة عن خريطة
sessionKey -> { sessionId, updatedAt, ... }. حذف الإدخالات آمن؛ يتم إعادة إنشائها عند الطلب. - قد تتضمن إدخالات المجموعة
displayName,channel,subject,room, وspaceلوضع تسميات للجلسات في واجهات المستخدم. - تتضمن إدخالات الجلسة بيانات وصفية
origin(تسمية + تلميحات التوجيه) حتى تتمكن واجهات المستخدم من شرح مصدر الجلسة. - لا تقرأ OpenClaw مجلدات جلسات Pi/Tau القديمة.
الصيانة
تطبق OpenClaw صيانة مخزن الجلسات للحفاظ على sessions.json وقطع النصوص محدودة مع مرور الوقت.
الإعدادات الافتراضية
session.maintenance.mode:warnsession.maintenance.pruneAfter:30dsession.maintenance.maxEntries:500session.maintenance.rotateBytes:10mbsession.maintenance.resetArchiveRetention: الافتراضي هوpruneAfter(30d)session.maintenance.maxDiskBytes: غير مضبوط (معطل)session.maintenance.highWaterBytes: الافتراضي هو80%منmaxDiskBytesعند تمكين الميزانية
كيفية عملها
تعمل الصيانة أثناء كتابات مخزن الجلسات، ويمكنك تشغيلها عند الطلب باستخدام openclaw sessions cleanup.
mode: "warn": يبلغ عما سيتم إزالته ولكن لا يغير الإدخالات/النصوص.mode: "enforce": يطبق التنظيف بهذا الترتيب:- إزالة الإدخالات القديمة الأقدم من
pruneAfter - تحديد عدد الإدخالات بـ
maxEntries(الأقدم أولاً) - أرشفة ملفات النصوص للإدخالات المزالة التي لم يعد يتم الإشارة إليها
- تطهير الأرشيفات القديمة
*.deleted.<timestamp>و*.reset.<timestamp>حسب سياسة الاحتفاظ - تدوير
sessions.jsonعندما يتجاوزrotateBytes - إذا تم ضبط
maxDiskBytes، فرض ميزانية القرص نحوhighWaterBytes(أقدم القطع أولاً، ثم أقدم الجلسات)
- إزالة الإدخالات القديمة الأقدم من
تحذير الأداء للمخازن الكبيرة
مخازن الجلسات الكبيرة شائعة في الإعدادات عالية الحجم. عمل الصيانة هو عمل في مسار الكتابة، لذا يمكن للمخازن الكبيرة جداً زيادة زمن الاستجابة للكتابة. ما يزيد التكلفة أكثر:
- قيم
session.maintenance.maxEntriesعالية جداً - نوافذ
pruneAfterطويلة تحتفظ بالإدخالات القديمة - العديد من قطع النصوص/الأرشيفات في
~/.openclaw/agents/<agentId>/sessions/ - تمكين ميزانيات القرص (
maxDiskBytes) دون حدود تقليم/سقف معقولة
ما يجب فعله:
- استخدم
mode: "enforce"في الإنتاج بحيث يكون النمو محدوداً تلقائياً - اضبط كلاً من حدود الوقت والعدد (
pruneAfter+maxEntries)، وليس واحداً فقط - اضبط
maxDiskBytes+highWaterBytesلحدود عليا صارمة في النشرات الكبيرة - حافظ على
highWaterBytesأقل بشكل معنوي منmaxDiskBytes(الافتراضي هو 80%) - شغّل
openclaw sessions cleanup --dry-run --jsonبعد تغييرات التكوين للتحقق من التأثير المتوقع قبل التنفيذ - للجلسات النشطة المتكررة، مرّر
--active-keyعند تشغيل التنظيف اليدوي
أمثلة التخصيص
استخدم سياسة تنفيذ محافظة:
{
session: {
maintenance: {
mode: "enforce",
pruneAfter: "45d",
maxEntries: 800,
rotateBytes: "20mb",
resetArchiveRetention: "14d",
},
},
}
تمكين ميزانية قرص صارمة لمجلد الجلسات:
{
session: {
maintenance: {
mode: "enforce",
maxDiskBytes: "1gb",
highWaterBytes: "800mb",
},
},
}
ضبط للتركيبات الأكبر (مثال):
{
session: {
maintenance: {
mode: "enforce",
pruneAfter: "14d",
maxEntries: 2000,
rotateBytes: "25mb",
maxDiskBytes: "2gb",
highWaterBytes: "1.6gb",
},
},
}
معاينة أو فرض الصيانة من CLI:
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
تقليم الجلسات
تقوم OpenClaw بقص نتائج الأدوات القديمة من السياق في الذاكرة مباشرة قبل استدعاءات LLM افتراضياً. هذا لا يعيد كتابة تاريخ JSONL. انظر /concepts/session-pruning.
تفريغ الذاكرة قبل الضغط
عندما تقترب جلسة من الضغط التلقائي، يمكن لـ OpenClaw تشغيل دورة تفريغ ذاكرة صامتة تذكر النموذج بكتابة ملاحظات دائمة على القرص. يعمل هذا فقط عندما تكون مساحة العمل قابلة للكتابة. انظر الذاكرة والضغط.
تعيين وسائط النقل → مفاتيح الجلسات
- تتبع المحادثات المباشرة
session.dmScope(الافتراضيmain).main:agent:<agentId>:<mainKey>(استمرارية عبر الأجهزة/القنوات).- يمكن لعدة أرقام هواتف وقنوات التعيين إلى نفس المفتاح الرئيسي للوكيل؛ تعمل كوسائط نقل إلى محادثة واحدة.
per-peer:agent:<agentId>:dm:<peerId>.per-channel-peer:agent:<agentId>:<channel>:dm:<peerId>.per-account-channel-peer:agent:<agentId>:<channel>:<accountId>:dm:<peerId>(accountId الافتراضي هوdefault).- إذا طابقت
session.identityLinksهوية قرين ذات بادئة مزود (على سبيل المثالtelegram:123)، فإن المفتاح القياسي يحل محل<peerId>بحيث يشارك نفس الشخص جلسة عبر القنوات.
- محادثات المجموعة تعزل الحالة:
agent:<agentId>:<channel>:group:<id>(الغرف/القنوات تستخدمagent:<agentId>:<channel>:channel:<id>).- مواضيع منتدى Telegram تُلحق
:topic:<threadId>بمعرف المجموعة للعزل. - لا تزال مفاتيح
group:<id>القديمة معترف بها للهجرة.
- مواضيع منتدى Telegram تُلحق
- قد تستخدم السياقات الواردة
group:<id>؛ يتم استنتاج القناة منProviderوتطبيعها إلى الصيغة القياسيةagent:<agentId>:<channel>:group:<id>. - مصادر أخرى:
- مهام Cron:
cron:<job.id> - Webhooks:
hook:<uuid>(ما لم يتم ضبطها صراحةً بواسطة الـ hook) - عمليات Node:
node-<nodeId>
- مهام Cron:
دورة الحياة
- سياسة إعادة التعيين: يتم إعادة استخدام الجلسات حتى تنتهي صلاحيتها، ويتم تقييم انتهاء الصلاحية عند الرسالة الواردة التالية.
- إعادة التعيين اليومية: الافتراضي هو الساعة 4:00 صباحاً بالتوقيت المحلي على مضيف البوابة. تصبح الجلسة قديمة بمجرد أن يكون آخر تحديث لها أقدم من وقت إعادة التعيين اليومي الأحدث.
- إعادة التعيين بسبب الخمول (اختياري):
idleMinutesيضيف نافذة خمول منزلقة. عند تكوين كل من إعادة التعيين اليومية وبسبب الخمول، أيهما ينتهي أولاً يجبر على جلسة جديدة. - الخمول فقط القديم: إذا قمت بضبط
session.idleMinutesدون أي تكوينsession.reset/resetByType، تبقى OpenClaw في وضع الخمول فقط للتوافق مع الإصدارات السابقة. - تجاوزات حسب النوع (اختياري):
resetByTypeيتيح لك تجاوز السياسة لجلساتdirect، وgroup، وthread(thread = سلاسل Slack/Discord، مواضيع Telegram، سلاسل Matrix عندما يوفرها الموصل). - تجاوزات حسب القناة (اختياري):
resetByChannelيتجاوز سياسة إعادة التعيين لقناة (ينطبق على جميع أنواع الجلسات لتلك القناة ويأخذ الأولوية علىreset/resetByType). - محفزات إعادة التعيين:
/newأو/resetالدقيقة (بالإضافة إلى أي إضافات فيresetTriggers) تبدأ معرف جلسة جديد وتمرر باقي الرسالة./new <model>يقبل اسم نموذج، أوprovider/model، أو اسم مزود (مطابقة تقريبية) لتعيين نموذج الجلسة الجديد. إذا أُرسل/newأو/resetبمفرده، تشغل OpenClaw دورة "ترحيب" قصيرة لتأكيد إعادة التعيين. - إعادة التعيين اليدوي: احذف مفاتيح محددة من المخزن أو أزل نص JSONL؛ الرسالة التالية تعيد إنشائها.
- مهام Cron المعزولة تصنع دائماً
sessionIdجديد لكل تشغيل (لا إعادة استخدام بسبب الخمول).
سياسة الإرسال (اختياري)
منع التسليم لأنواع جلسات محددة دون سرد معرفات فردية.
{
session: {
sendPolicy: {
rules: [
{ action: "deny", match: { channel: "discord", chatType: "group" } },
{ action: "deny", match: { keyPrefix: "cron:" } },
// مطابقة مفتاح الجلسة الخام (بما في ذلك البادئة `agent:<id>:`).
{ action: "deny", match: { rawKeyPrefix: "agent:main:discord:" } },
],
default: "allow",
},
},
}
تجاوز وقت التشغيل (للمالك فقط):
/send on→ السماح لهذه الجلسة/send off→ الرفض لهذه الجلسة/send inherit→ مسح التجاوز واستخدام قواعد التكوين أرسل هذه كرسائل منفردة حتى يتم تسجيلها.
التكوين (مثال إعادة تسمية اختياري)
// ~/.openclaw/openclaw.json
{
session: {
scope: "per-sender", // احتفظ بمفاتيح المجموعة منفصلة
dmScope: "main", // استمرارية الرسائل المباشرة (اضبط per-channel-peer/per-account-channel-peer للصناديق الواردة المشتركة)
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"],
},
reset: {
// الافتراضيات: mode=daily, atHour=4 (التوقيت المحلي لمضيف البوابة).
// إذا قمت أيضاً بضبط idleMinutes، أيهما ينتهي أولاً يفوز.
mode: "daily",
atHour: 4,
idleMinutes: 120,
},
resetByType: {
thread: { mode: "daily", atHour: 4 },
direct: { mode: "idle", idleMinutes: 240 },
group: { mode: "idle", idleMinutes: 120 },
},
resetByChannel: {
discord: { mode: "idle", idleMinutes: 10080 },
},
resetTriggers: ["/new", "/reset"],
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
mainKey: "main",
},
}
الفحص
openclaw status— يظهر مسار المخزن والجلسات الحديثة.openclaw sessions --json— يفرغ كل إدخال (فلترة باستخدام--active <minutes>).openclaw gateway call sessions.list --params '{}'— جلب الجلسات من البوابة قيد التشغيل (استخدم--url/--tokenللوصول إلى البوابة البعيدة).- أرسل
/statusكرسالة منفردة في الدردشة لمعرفة ما إذا كان الوكيل يمكن الوصول إليه، وكم من سياق الجلسة مستخدم، وتبديلات التفكير/التفصيل الحالية، ومتى تم تحديث بيانات اعتماد WhatsApp web الخاصة بك آخر مرة (يساعد في اكتشاف احتياجات إعادة الربط). - أرسل
/context listأو/context detailلرؤية ما في موجه النظام وملفات مساحة العمل المحقونة (وأكبر المساهمين في السياق). - أرسل
/stop(أو عبارات إلغاء منفردة مثلstop,stop action,stop run,stop openclaw) لإلغاء التشغيل الحالي، ومسح المتابعات في قائمة الانتظار لتلك الجلسة، وإيقاف أي تشغيلات وكيل فرعي ناتجة منها (يشمل الرد عدد ما تم إيقافه). - أرسل
/compact(تعليمات اختيارية) كرسالة منفردة لتلخيص السياق الأقدم وتحرير مساحة النافذة. انظر /concepts/compaction. - يمكن فتح نصوص JSONL مباشرة لمراجعة الدورات الكاملة.
نصائح
- احتفظ بالمفتاح الأساسي مخصصاً لحركة المرور من واحد لواحد؛ دع المجموعات تحتفظ بمفاتيحها الخاصة.
- عند أتمتة التنظيف، احذف مفاتيح فردية بدلاً من المخزن بالكامل للحفاظ على السياق في أماكن أخرى.
بيانات وصفية لأصل الجلسة
يسجل كل إدخال جلسة من أين أتى (بأفضل جهد) في origin:
label: تسمية بشرية (تم حلها من تسمية المحادثة + موضوع/قناة المجموعة)provider: معرف قناة موحد (بما في ذلك الامتدادات)from/to: معرفات التوجيه الخام من المغلف الواردaccountId: معرف حساب المزود (عند تعدد الحسابات)threadId: معرف سلسلة/موضوع عندما تدعم القناة ذلك يتم تعبئة حقول الأصل للرسائل المباشرة والقنوات والمجموعات. إذا قام الموصل بتحديث توجيه التسليم فقط (على سبيل المثال، للحفاظ على جلسة الرسائل المباشرة الرئيسية جديدة)، فيجب أن يزال يوفر سياقاً وارداً حتى تحتفظ الجلسة ببياناتها التوضيحية. يمكن للامتدادات القيام بذلك عن طريق إرسالConversationLabel,GroupSubject,GroupChannel,GroupSpace, وSenderNameفي السياق الوارد واستدعاءrecordSessionMetaFromInbound(أو تمرير نفس السياق إلىupdateLastRoute).