أدوات الجلسات
الهدف: مجموعة أدوات صغيرة يصعب إساءة استخدامها حتى يتمكن الوكلاء من سرد الجلسات، واسترجاع السجل، والإرسال إلى جلسة أخرى.
أسماء الأدوات
sessions_listsessions_historysessions_sendsessions_spawn
النموذج الرئيسي
- دلو الدردشة المباشر الرئيسي هو دائمًا المفتاح الحرفي
"main"(يتم حله إلى المفتاح الرئيسي للوكيل الحالي). - الدردشات الجماعية تستخدم
agent:<agentId>:<channel>:group:<id>أوagent:<agentId>:<channel>:channel:<id>(تمرير المفتاح الكامل). - الوظائف المجدولة تستخدم
cron:<job.id>. - الخطافات تستخدم
hook:<uuid>ما لم يتم تعيينها صراحةً. - جلسات العقدة تستخدم
node-<nodeId>ما لم يتم تعيينها صراحةً.
القيم global و unknown محجوزة ولا يتم سردها أبدًا. إذا كان session.scope = "global"، فإننا نستخدم الاسم المستعار main لجميع الأدوات بحيث لا يرى المتصلون global أبدًا.
sessions_list
سرد الجلسات كمصفوفة من الصفوف. المعلمات:
kinds?: string[]عامل تصفية: أي من"main" | "group" | "cron" | "hook" | "node" | "other"limit?: numberالحد الأقصى للصفوف (الافتراضي: الافتراضي للخادم، مع تحديد حد أعلى، على سبيل المثال 200)activeMinutes?: numberفقط الجلسات التي تم تحديثها خلال N دقيقةmessageLimit?: number0 = لا توجد رسائل (الافتراضي 0)؛ >0 = تضمين آخر N رسائل
السلوك:
messageLimit > 0يجلبchat.historyلكل جلسة ويتضمن آخر N رسائل.- يتم تصفية نتائج الأداة في مخرجات القائمة؛ استخدم
sessions_historyلرسائل الأداة. - عند التشغيل في جلسة وكيل معزولة (sandboxed)، فإن أدوات الجلسات تظهر بشكل افتراضي رؤية الجلسات المنشأة فقط (انظر أدناه).
شكل الصف (JSON):
key: مفتاح الجلسة (سلسلة نصية)kind:main | group | cron | hook | node | otherchannel:whatsapp | telegram | discord | signal | imessage | webchat | internal | unknowndisplayName(تسمية عرض المجموعة إذا كانت متاحة)updatedAt(مللي ثانية)sessionIdmodel,contextTokens,totalTokensthinkingLevel,verboseLevel,systemSent,abortedLastRunsendPolicy(تجاوز الجلسة إذا تم تعيينه)lastChannel,lastTodeliveryContext(مُطَّبَق{ channel, to, accountId }عند التوفر)transcriptPath(مسار مستمد بأفضل جهد من دليل التخزين + sessionId)messages?(فقط عندما يكونmessageLimit > 0)
sessions_history
جلب النص المسجل لجلسة واحدة. المعلمات:
sessionKey(مطلوب؛ يقبل مفتاح الجلسة أوsessionIdمنsessions_list)limit?: numberالحد الأقصى للرسائل (الخادم يحدد حدًا أعلى)includeTools?: boolean(الافتراضي false)
السلوك:
includeTools=falseيرشح رسائلrole: "toolResult".- يُرجع مصفوفة رسائل بتنسيق النص المسجل الخام.
- عند إعطاء
sessionId، يحل OpenClaw ذلك إلى مفتاح الجلسة المقابل (الأرقام المعرفية المفقودة تسبب خطأ).
sessions_send
إرسال رسالة إلى جلسة أخرى. المعلمات:
sessionKey(مطلوب؛ يقبل مفتاح الجلسة أوsessionIdمنsessions_list)message(مطلوب)timeoutSeconds?: number(الافتراضي >0؛ 0 = إرسال ونسيان)
السلوك:
timeoutSeconds = 0: يضيف إلى قائمة الانتظار ويعيد{ runId, status: "accepted" }.timeoutSeconds > 0: ينتظر حتى N ثانية للإكمال، ثم يعيد{ runId, status: "ok", reply }.- إذا انتهت مهلة الانتظار:
{ runId, status: "timeout", error }. يستمر التشغيل؛ استدعِsessions_historyلاحقًا. - إذا فشل التشغيل:
{ runId, status: "error", error }. - تشغيل إعلان التسليم يتم بعد اكتمال التشغيل الأساسي وهو بأفضل جهد؛
status: "ok"لا يضمن تسليم الإعلان. - الانتظار يتم عبر بوابة
agent.wait(على جانب الخادم) حتى لا يؤدي إعادة الاتصال إلى إسقاط الانتظار. - سياق الرسالة من وكيل إلى وكيل يتم حقنه للتشغيل الأساسي.
- يتم حفظ الرسائل بين الجلسات مع
message.provenance.kind = "inter_session"حتى يتمكن قراء النص المسجل من التمييز بين تعليمات الوكيل الموجهة والإدخال الخارجي من المستخدم. - بعد اكتمال التشغيل الأساسي، يقوم OpenClaw بتشغيل حلقة الرد:
- الجولة 2+ تتبادل بين وكيل الطالب والوكيل الهدف.
- الرد بـ
REPLY_SKIPبالضبط لإيقاف التبادل. - الحد الأقصى للدورات هو
session.agentToAgent.maxPingPongTurns(0–5، الافتراضي 5).
- بمجرد انتهاء الحلقة، يقوم OpenClaw بتشغيل خطوة الإعلان من وكيل إلى وكيل (الوكيل الهدف فقط):
- الرد بـ
ANNOUNCE_SKIPبالضبط للبقاء صامتًا. - أي رد آخر يتم إرساله إلى قناة الهدف.
- خطوة الإعلان تتضمن الطلب الأصلي + رد الجولة الأولى + أحدث رد تبادلي.
- الرد بـ
حقل القناة
- للمجموعات،
channelهو القناة المسجلة في إدخال الجلسة. - للدردشات المباشرة،
channelيتم تعيينه منlastChannel. - للوظائف المجدولة/الخطافات/العقد،
channelهوinternal. - إذا كان مفقودًا،
channelهوunknown.
الأمان / سياسة الإرسال
المنع القائم على السياسات حسب نوع القناة/الدردشة (ليس حسب معرف الجلسة).
{
"session": {
"sendPolicy": {
"rules": [
{
"match": { "channel": "discord", "chatType": "group" },
"action": "deny"
}
],
"default": "allow"
}
}
}
تجاوز وقت التشغيل (لكل إدخال جلسة):
sendPolicy: "allow" | "deny"(غير معين = يرث التكوين)- قابل للتعيين عبر
sessions.patchأو/send on|off|inheritللمالك فقط (رسالة مستقلة).
نقاط التنفيذ:
chat.send/agent(البوابة)- منطق تسليم الرد التلقائي
sessions_spawn
إنشاء تشغيل وكيل فرعي في جلسة معزولة والإعلان عن النتيجة مرة أخرى إلى قناة الدردشة للطالب. المعلمات:
task(مطلوب)label?(اختياري؛ يُستخدم للسجلات/واجهة المستخدم)agentId?(اختياري؛ الإنشاء تحت معرف وكيل آخر إذا كان مسموحًا)model?(اختياري؛ يتجاوز نموذج الوكيل الفرعي؛ القيم غير الصالحة تسبب خطأ)thinking?(اختياري؛ يتجاوى مستوى التفكير لتشغيل الوكيل الفرعي)runTimeoutSeconds?(الافتراضي هوagents.defaults.subagents.runTimeoutSecondsعند التعيين، وإلا0؛ عند التعيين، يلغي تشغيل الوكيل الفرعي بعد N ثانية)thread?(الافتراضي false؛ طلب التوجيه المرتبط بسلسلة المحادثة لهذا الإنشاء عند دعمه من قبل القناة/الملحق)mode?(run|session؛ الافتراضيrun، ولكن الافتراضي يصبحsessionعندما يكونthread=true؛mode="session"يتطلبthread=true)cleanup?(delete|keep، الافتراضيkeep)sandbox?(inherit|require، الافتراضيinherit؛requireيرفض الإنشاء ما لم يكن وقت تشغيل الهدف الفرعي معزولًا)attachments?(مصفوفة اختيارية للملفات المضمنة؛ وقت تشغيل الوكيل الفرعي فقط، ACP يرفض). كل إدخال:{ name, content, encoding?: "utf8" | "base64", mimeType? }. يتم تجسيد الملفات في مساحة العمل الفرعية في.openclaw/attachments/<uuid>/. يُرجع إيصالًا مع sha256 لكل ملف.attachAs?(اختياري؛{ mountPath? }تلميح محجوز لتطبيقات التثبيت المستقبلية)
قائمة السماح:
agents.list[].subagents.allowAgents: قائمة معرفات الوكلاء المسموح بها عبرagentId(["*"]للسماح بأي). الافتراضي: فقط وكيل الطالب.- حارس توريث العزل: إذا كانت جلسة الطالب معزولة، فإن
sessions_spawnيرفض الأهداف التي ستعمل بدون عزل.
الاكتشاف:
- استخدم
agents_listلاكتشاف معرفات الوكلاء المسموح بها لـsessions_spawn.
السلوك:
- يبدأ جلسة جديدة
agent:<agentId>:subagent:<uuid>معdeliver: false. - الوكلاء الفرعيون لديهم بشكل افتراضي مجموعة الأدوات الكاملة مطروحًا منها أدوات الجلسات (قابل للتكوين عبر
tools.subagents.tools). - لا يُسمح للوكلاء الفرعيين باستدعاء
sessions_spawn(لا إنشاء وكيل فرعي → وكيل فرعي). - دائمًا غير محظور: يعيد
{ status: "accepted", runId, childSessionKey }فورًا. - مع
thread=true، يمكن لوصلات القنوات ربط التسليم/التوجيه بهدف سلسلة المحادثة (دعم Discord يتم التحكم فيه بواسطةsession.threadBindings.*وchannels.discord.threadBindings.*). - بعد الاكتمال، يقوم OpenClaw بتشغيل خطوة إعلان الوكيل الفرعي وينشر النتيجة إلى قناة الدردشة للطالب.
- إذا كان رد المساعد النهائي فارغًا، يتم تضمين أحدث
toolResultمن سجل الوكيل الفرعي كـResult.
- إذا كان رد المساعد النهائي فارغًا، يتم تضمين أحدث
- الرد بـ
ANNOUNCE_SKIPبالضبط أثناء خطوة الإعلان للبقاء صامتًا. - يتم تطبيع ردود الإعلان إلى
Status/Result/Notes؛Statusيأتي من نتيجة وقت التشغيل (وليس نص النموذج). - يتم أرشفة جلسات الوكيل الفرعي تلقائيًا بعد
agents.defaults.subagents.archiveAfterMinutes(الافتراضي: 60). - تتضمن ردود الإعلان سطر إحصائيات (وقت التشغيل، الرموز، sessionKey/sessionId، مسار النص المسجل، والتكلفة الاختيارية).
رؤية الجلسة المعزولة
يمكن تحديد نطاق أدوات الجلسات لتقليل الوصول عبر الجلسات. السلوك الافتراضي:
tools.sessions.visibilityالافتراضي هوtree(الجلسة الحالية + جلسات الوكيل الفرعي المنشأة).- للجلسات المعزولة، يمكن لـ
agents.defaults.sandbox.sessionToolsVisibilityتحديد الرؤية بقوة.
التكوين:
{
tools: {
sessions: {
// "self" | "tree" | "agent" | "all"
// default: "tree"
visibility: "tree",
},
},
agents: {
defaults: {
sandbox: {
// default: "spawned"
sessionToolsVisibility: "spawned", // or "all"
},
},
},
}
ملاحظات:
self: فقط مفتاح الجلسة الحالي.tree: الجلسة الحالية + الجلسات المنشأة بواسطة الجلسة الحالية.agent: أي جلسة تنتمي إلى معرف الوكيل الحالي.all: أي جلسة (الوصول عبر الوكلاء لا يزال يتطلبtools.agentToAgent).- عندما تكون الجلسة معزولة و
sessionToolsVisibility="spawned"، يحدد OpenClaw الرؤية إلىtreeحتى إذا قمت بتعيينtools.sessions.visibility="all".