إدارة الجلسات¶
يتعامل 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: {
// Secure DM mode: isolate DM context per channel + sender.
dmScope: "per-channel-peer",
},
}
متى يجب تمكين هذا:
- لديك موافقات إقران لأكثر من مُرسِل واحد
- أنت تستخدم قائمة مسموح DM مع إدخالات متعددة
- تضبط
dmPolicy: "open" - يمكن لأرقام هواتف أو حسابات متعددة مراسلة وكيلك
ملاحظات:
- الافتراضي هو
dmScope: "main"للاستمرارية (تشارك جميع الرسائل المباشرة الجلسة الرئيسية). هذا مناسب لإعدادات المستخدم الواحد. - لصناديق الوارد متعددة الحسابات على القناة نفسها، يُفضَّل
per-account-channel-peer. - إذا تواصل الشخص نفسه معك عبر قنوات متعددة، استخدم
session.identityLinksلدمج جلسات الرسائل المباشرة في هوية معيارية واحدة. - يمكنك التحقق من إعدادات الرسائل المباشرة لديك باستخدام
openclaw security audit(انظر الأمان).
الـ Gateway هو مصدر الحقيقة¶
تعود ملكية حالة الجلسة بالكامل إلى Gateway (النسخة «الرئيسية» من OpenClaw). عملاء واجهة المستخدم (تطبيق لاكوس، WebChat، إلخ.) يجب على عملاء واجهة المستخدم (تطبيق macOS، WebChat، إلخ) الاستعلام من الـ Gateway عن قوائم الجلسات وعدّادات الرموز بدل قراءة الملفات المحلية.
- في الوضع البعيد، يوجد مخزن الجلسات الذي يهمك على مضيف Gateway البعيد، وليس على جهاز Mac لديك.
- تأتي عدّادات الرموز المعروضة في واجهات المستخدم من حقول مخزن الـ Gateway (
inputTokensوoutputTokensوtotalTokensوcontextTokens). لا تقوم العملاء بتحليل نصوص JSONL «لتصحيح» الإجماليات.
أين تعيش الحالة¶
- على مضيف Gateway:
- ملف المخزن:
~/.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 افتراضيًا بقص نتائج الأدوات القديمة من السياق الموجود في الذاكرة مباشرة قبل استدعاءات 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>القديمة معترفًا بها لأغراض الترحيل. - قد تستخدم السياقات الواردة ما يزال
group:<id>؛ تُستنتج القناة منProviderوتُطبَّع إلى الصيغة المعياريةagent:<agentId>:<channel>:group:<id>. - مصادر أخرى:
- مهام Cron:
cron:<job.id> - Webhooks:
hook:<uuid>(ما لم يُحدَّد صراحة بواسطة الخطاف) - تشغيل العُقد:
node-<nodeId>
دورة الحياة¶
- سياسة إعادة الضبط: تُعاد استخدام الجلسات حتى تنتهي صلاحيتها، ويُقيَّم الانتهاء عند الرسالة الواردة التالية.
- إعادة ضبط يومية: الافتراضي الساعة 4:00 صباحًا بالتوقيت المحلي على مضيف Gateway. تُعد الجلسة قديمة إذا كان آخر تحديث لها أقدم من أحدث وقت لإعادة الضبط اليومية.
- إعادة ضبط الخمول (اختياري): يضيف
idleMinutesنافذة خمول منزلقة. عند تكوين كلٍ من إعادة الضبط اليومية والخمول، فإن الأقرب انتهاءً يفرض جلسة جديدة. - الخمول فقط (قديم): إذا ضبطت
session.idleMinutesدون أي تهيئةsession.reset/resetByType، يبقى OpenClaw في وضع الخمول فقط للتوافق العكسي. - // ~/.openclaw/openclaw.json { session: { scope: "per-sender", // keep group keys separate dmScope: "main", // DM continuity (set per-channel-peer/per-account-channel-peer for shared inboxes) identityLinks: { alice: ["telegram:123456789", "discord:987654321012345678"], }, reset: { // Defaults: mode=daily, atHour=4 (gateway host local time). // If you also set idleMinutes, whichever expires first wins. 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", }, }
- تجاوزات حسب القناة (اختياري): يتجاوز
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:" } },
],
default: "allow",
},
},
}
تجاوز وقت التشغيل (للمالك فقط):
/send on→ السماح لهذه الجلسة/send off→ الرفض لهذه الجلسة/send inherit→ مسح التجاوز واستخدام قواعد التهيئة أرسل هذه كرسائل مستقلة لكي تُسجَّل.
التهيئة (مثال إعادة تسمية اختياري)¶
{
session: {
scope: "per-sender",
dmScope: "main",
identityLinks: {
alice: ["telegram:123456789", "discord:987654321012345678"],
},
reset: {
mode: "daily",
atHour: 4,
idleMinutes: 60,
},
resetByType: {
thread: { mode: "daily", atHour: 4 },
direct: { mode: "idle", idleMinutes: 240 },
group: { mode: "idle", idleMinutes: 120 },
},
resetTriggers: ["/new", "/reset"],
// Default is already per-agent under ~/.openclaw/agents/<agentId>/sessions/sessions.json
// You can override with {agentId} templating:
store: "~/.openclaw/agents/{agentId}/sessions/sessions.json",
// Direct chats collapse to agent:<agentId>:<mainKey> (default: "main").
mainKey: "main",
agentToAgent: {
// Max ping-pong reply turns between requester/target (0–5).
maxPingPongTurns: 5,
},
sendPolicy: {
rules: [{ action: "deny", match: { channel: "discord", chatType: "group" } }],
default: "allow",
},
},
}
الفحص¶
openclaw status— يعرض مسار المخزن والجلسات الأخيرة.openclaw sessions --json— يفرغ كل إدخال (التصفية باستخدام--active <minutes>).openclaw gateway call sessions.list --params '{}'— يجلب الجلسات من Gateway العامل (استخدم--url/--tokenللوصول إلى Gateway بعيد).- أرسل
/statusكرسالة مستقلة في الدردشة لمعرفة ما إذا كان الوكيل متاحًا، وكمية سياق الجلسة المستخدمة، ومفاتيح التفكير/الإسهاب الحالية، وموعد آخر تحديث لاعتمادات WhatsApp Web (يساعد على اكتشاف الحاجة لإعادة الربط). - أرسل
/context listأو/context detailلمعرفة ما الموجود في موجه النظام وملفات مساحة العمل المحقونة (وأكبر المساهمين في السياق). - أرسل
/stopكرسالة مستقلة لإيقاف التشغيل الحالي، ومسح المتابعات الموضوعة في الطابور لتلك الجلسة، وإيقاف أي تشغيلات لوكلاء فرعيين انبثقت منها (يتضمن الرد عدد الإيقافات). - أرسل
/compact(تعليمات اختيارية) كرسالة مستقلة لتلخيص السياق الأقدم وتحرير مساحة النافذة. انظر /concepts/compaction. - يمكن فتح نصوص JSONL مباشرة لمراجعة الدورات كاملة.
نصائح¶
- أبقِ المفتاح الرئيسي مخصصًا لحركة 1:1؛ ودَع المجموعات تحتفظ بمفاتيحها الخاصة.
- عند أتمتة التنظيف، احذف المفاتيح الفردية بدل المخزن كاملًا للحفاظ على السياق في أماكن أخرى.
بيانات التعريف أصل الجلسة¶
يسجّل كل إدخال جلسة مصدره (بأفضل جهد) في origin:
label: تسمية بشرية (محلولة من تسمية المحادثة + موضوع المجموعة/القناة)provider: معرّف قناة مُطبَّع (بما في ذلك الامتدادات)from/to: معرّفات توجيه خام من الغلاف الواردaccountId: معرّف حساب الموفّر (عند تعدد الحسابات)threadId: معرّف السلسلة/الموضوع عندما تدعم القناة ذلك تُملأ حقول المصدر للرسائل المباشرة والقنوات والمجموعات. إذا كان الموصل يحدّث توجيه التسليم فقط (على سبيل المثال، للحفاظ على حداثة الجلسة الرئيسية للرسائل المباشرة)، فيجب عليه مع ذلك توفير سياق وارد كي تحتفظ الجلسة ببياناتها التوضيحية. يمكن للامتدادات القيام بذلك بإرسالConversationLabelوGroupSubjectوGroupChannelوGroupSpaceوSenderNameفي السياق الوارد واستدعاءrecordSessionMetaFromInbound(أو تمرير السياق نفسه إلىupdateLastRoute).