---
read_when:
    - تحتاج إلى تصحيح أخطاء معرّفات الجلسات أو أحداث النصوص المفرّغة أو حقول صفوف الجلسات
    - أنت تغيّر سلوك Compaction التلقائي أو تضيف مهام صيانة «قبل Compaction»
    - تريد تنفيذ عمليات تفريغ الذاكرة أو أدوار النظام الصامتة
summary: 'نظرة متعمقة: مخزن الجلسات + النصوص المفرغة، ودورة الحياة، وآليات Compaction (التلقائي) الداخلية'
title: نظرة متعمقة على إدارة الجلسات
x-i18n:
    generated_at: "2026-07-16T15:01:53Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    prompt_version: 32
    provider: openai
    source_hash: 7551a94a4e2dc8be8b69503795309d0200cc3b5d7231b54083dbcaade697b06c
    source_path: reference/session-management-compaction.md
    workflow: 16
---

تتولى **عملية Gateway واحدة** حالة الجلسة من البداية إلى النهاية. تستعلم واجهات المستخدم (تطبيق macOS، وواجهة Control UI على الويب، وTUI) من Gateway عن قوائم الجلسات وأعداد الرموز. في الوضع البعيد، توجد ملفات الجلسات على المضيف البعيد، لذا لن يعكس فحص ملفات جهاز Mac المحلي ما يستخدمه Gateway.

ابدأ بوثائق النظرة العامة: [إدارة الجلسات](/ar/concepts/session)، و[Compaction](/ar/concepts/compaction)، و[نظرة عامة على الذاكرة](/ar/concepts/memory)، و[البحث في الذاكرة](/ar/concepts/memory-search)، و[تنقيح الجلسات](/ar/concepts/session-pruning)، و[سلامة السجل النصي](/ar/reference/transcript-hygiene)، ومرجع الإعداد الكامل في [إعداد الوكيل](/ar/gateway/config-agents).

## طبقتا الاستمرارية

1. **صفوف الجلسات (SQLite لكل وكيل)** - خريطة مفاتيح/قيم `sessionKey -> SessionEntry`. حالة تشغيل قابلة للتغيير يملكها Gateway. تتعقب البيانات الوصفية: معرّف الجلسة الحالي، وآخر نشاط، وخيارات التبديل، وعدادات الرموز.
2. **أحداث السجل النصي (SQLite لكل وكيل)** - للإلحاق فقط، ومنظمة على هيئة شجرة (تحتوي الإدخالات على `id` + `parentId`). تخزن المحادثة واستدعاءات الأدوات وملخصات Compaction؛ وتعيد بناء سياق النموذج للمنعطفات المستقبلية. نقاط تحقق Compaction هي بيانات وصفية فوق السجل النصي اللاحق الذي خضع للضغط - ولا تكتب عملية Compaction جديدة نسخة `.checkpoint.*.jsonl` ثانية.

قد تظل عمليات التثبيت القديمة تحتوي على ملفات `sessions.json` ضمن دليل الوكيل `sessions/`.
تعامل مع هذه الملفات على أنها مدخلات لترحيل صفوف الجلسات القديمة أو أهداف صيانة صريحة
دون اتصال. يستورد بدء تشغيل Gateway و`openclaw doctor --fix` الصفوف القديمة النشطة
وسجل السجلات النصية إلى مخزن SQLite الخاص بكل وكيل
تلقائيًا. شغّل `openclaw doctor --session-sqlite inspect
--session-sqlite-all-agents`، ثم اتبع [تسلسل ترحيل Doctor
](/ar/cli/doctor#session-sqlite-migration)، عندما تحتاج إلى دليل صريح
للفحص أو التحقق. إذا فشل ترحيل بعد أرشفة عناصر السجل النصي
القديمة، فاستخدم وضع استرداد Doctor من ذلك التسلسل.
يستخدم الاسترداد بيانات توصيف الترحيل، ويستعيد فقط عناصر الدعم المؤرشفة
المتأثرة، ويُعد تقرير مشكلة منقحًا على GitHub عند طلبه، ولا
يجعل وقت التشغيل النشط يقرأ ملفات JSONL مجددًا.

تتجنب قارئات سجل Gateway تجسيد السجل النصي كاملًا ما لم يحتج السطح إلى وصول عشوائي إلى السجل التاريخي. تستخدم الصفحة الأولى من السجل، وسجل الدردشة المضمّن، والاسترداد بعد إعادة التشغيل، وفحوص الرموز/الاستخدام قراءات محدودة من ذيل SQLite. تمر عمليات المسح الكامل للسجل النصي عبر فهرس السجل النصي غير المتزامن، وتكون مشتركة بين القارئات المتزامنة.

## المواقع على القرص

لكل وكيل، على مضيف Gateway (يُحل عبر `src/config/sessions.ts`):

- مخزن صفوف جلسات وقت التشغيل: `~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite`
- صفوف سجلات وقت التشغيل النصية: `~/.openclaw/agents/<agentId>/agent/openclaw-agent.sqlite`
- عناصر السجلات النصية القديمة/المؤرشفة: `~/.openclaw/agents/<agentId>/sessions/`
- مدخل ترحيل الصفوف القديمة: `~/.openclaw/agents/<agentId>/sessions/sessions.json`

## صيانة المخزن وضوابط القرص

يتحكم `session.maintenance` في الصيانة التلقائية لصفوف جلسات SQLite، وصفوف سجلات SQLite النصية، وعناصر الأرشيف، والملفات الجانبية للمسارات:

| المفتاح                     | الافتراضي               | ملاحظات                                                                                       |
| ----------------------- | --------------------- | ------------------------------------------------------------------------------------------- |
| `mode`                  | `"enforce"`           | أو `"warn"` (إبلاغ فقط، دون تعديل)                                                      |
| `pruneAfter`            | `"30d"`               | حد عمر الإدخالات القديمة                                                                      |
| `maxEntries`            | `500`                 | الحد الأقصى لإدخالات الجلسات                                                                      |
| `resetArchiveRetention` | الاحتفاظ (دون حد للعمر)  | حد عمر أرشيفات السجل النصي `*.reset.*`/`*.deleted.*`؛ وتؤدي مدة محددة إلى تفعيل الحذف |
| `maxDiskBytes`          | `2gb`                 | ميزانية قرص الجلسات لكل وكيل؛ يعطّلها `false`                                            |
| `highWaterBytes`        | 80% من `maxDiskBytes` | الهدف بعد تنظيف الميزانية                                                                 |

يُحتفظ بالسجلات النصية المؤرشفة افتراضيًا وتُضغط باستخدام zstd (`*.jsonl.<reason>.<timestamp>.zst`) عندما يدعم وقت التشغيل ذلك، بحيث لا يؤدي حذف جلسة أو إعادة تعيينها إلى التخلص بصمت من سجل المحادثة. تُخرج ميزانية القرص أقدم الأرشيفات أولًا، قبل المساس بالجلسات النشطة.

يقيس الإنفاذ النشط لـ `maxDiskBytes` في SQLite بايتات JSON لصف الجلسة إضافة إلى بايتات JSON لأحداث السجل النصي لكل جلسة؛ بينما يقيس إنفاذ الصيانة القديمة دون اتصال الملفات الموجودة في دليل الجلسات المحدد.

تحصل جلسات فحص تشغيل نموذج Gateway (المفاتيح المطابقة لـ `agent:*:explicit:model-run-<uuid>`) على مدة احتفاظ ثابتة ومنفصلة `24h`. يخضع هذا التنقيح لضغط السعة: فلا يعمل إلا عند بلوغ ضغط صيانة/حد إدخالات الجلسات، وفقط قبل خطوة التنظيف/الحد العامة للإدخالات القديمة. لا تستخدم الجلسات الصريحة الأخرى مدة الاحتفاظ هذه.

ترتيب الإنفاذ لتنظيف ميزانية القرص (`mode: "enforce"`):

1. أزل أولًا أقدم عناصر السجل النصي المؤرشفة، أو العناصر القديمة اليتيمة، أو عناصر المسارات اليتيمة.
2. إذا ظل الاستخدام أعلى من الهدف، فأخرج أقدم إدخالات الجلسات وصفوف سجلاتها النصية أو عناصر مساراتها.
3. كرر حتى يصبح الاستخدام مساويًا لـ `highWaterBytes` أو أقل منه.

يبلغ `mode: "warn"` عن عمليات الإخراج المحتملة دون تعديل المخزن أو الملفات.

شغّل الصيانة عند الطلب:

```bash
openclaw sessions cleanup --dry-run
openclaw sessions cleanup --enforce
```

تحافظ الصيانة على مؤشرات المحادثات الخارجية الدائمة مثل جلسات المجموعات وجلسات الدردشة ذات نطاق سلاسل المحادثة، لكن يمكن مع ذلك إزالة إدخالات وقت التشغيل الاصطناعية (cron، والخطافات، وHeartbeat، وACP، والوكلاء الفرعيين) بعد تجاوزها العمر أو العدد أو ميزانية القرص المضبوطة. تستخدم عمليات cron المعزولة عنصر تحكم منفصلًا `cron.sessionRetention`، مستقلًا عن مدة الاحتفاظ بفحوص تشغيل النموذج.

تمر كتابات Gateway العادية عبر موصل الجلسات، الذي يسلسل تعديلات SQLite لكل وكيل عبر مسار كاتب وقت التشغيل. ينبغي أن تفضل شيفرة وقت التشغيل مساعدات الموصل في `src/config/sessions/session-accessor.ts`؛ أما مساعدات `sessions.json` القديمة فهي أدوات للترحيل والصيانة دون اتصال. عندما يكون Gateway قابلًا للوصول، تفوض عمليتا `openclaw sessions cleanup` و`openclaw agents delete` غير التجريبيتين تعديلات المخزن إلى Gateway لكي ينضم التنظيف إلى قائمة انتظار الكاتب نفسها؛ ويمثل `--store <path>` مسار الإصلاح الصريح دون اتصال لمخزن قديم محدد، ويظل محليًا دائمًا (وكذلك `--dry-run`). يُنفذ تنظيف `maxEntries` على دفعات للمخازن ذات الحجم الإنتاجي، لذلك قد يتجاوز المخزن الحد المضبوط لفترة وجيزة قبل أن تعيد عملية تنظيف مستوى الامتلاء المرتفع التالية كتابته إلى ما دون الحد. لا تنقّح عمليات القراءة الإدخالات ولا تفرض حدًا عليها أثناء بدء تشغيل Gateway - لا تفعل ذلك إلا عمليات الكتابة أو `openclaw sessions cleanup --enforce`، كما يطبق الأخير الحد فورًا وينقّح عناصر السجل النصي ونقاط التحقق والمسارات القديمة غير المُشار إليها حتى مع عدم ضبط ميزانية للقرص.

لم يعد OpenClaw ينشئ نسخ تدوير احتياطية تلقائية `sessions.json.bak.*` أثناء كتابات Gateway. يرفض المخطط الحالي المفتاح القديم `session.maintenance.rotateBytes`، ويزيله `openclaw doctor --fix` من الإعدادات القديمة.

تستخدم تعديلات السجل النصي قائمة انتظار كتابة الجلسة لهدف سجل SQLite النصي:

| الإعداد                              | الافتراضي   | تجاوز متغير البيئة                                     |
| ------------------------------------ | --------- | ------------------------------------------------ |
| `session.writeLock.acquireTimeoutMs` | `60000`   | `OPENCLAW_SESSION_WRITE_LOCK_ACQUIRE_TIMEOUT_MS` |
| `session.writeLock.staleMs`          | `1800000` | `OPENCLAW_SESSION_WRITE_LOCK_STALE_MS`           |
| `session.writeLock.maxHoldMs`        | `300000`  | `OPENCLAW_SESSION_WRITE_LOCK_MAX_HOLD_MS`        |

يمثل `acquireTimeoutMs` المدة التي ينتظرها القفل قبل إظهار خطأ انشغال الجلسة والاستسلام؛ ولا تزده إلا عندما تتنافس عمليات التحضير أو التنظيف أو Compaction أو عكس السجل النصي المشروعة لمدة أطول على الأجهزة البطيئة. يحدد `staleMs` متى يمكن استرداد قفل موجود باعتباره قديمًا. يمثل `maxHoldMs` حد تحرير المراقب داخل العملية.

### الرجوع إلى إصدار أقدم بعد الانتقال إلى SQLite

استعد عناصر السجل النصي القديمة المؤرشفة قبل تشغيل إصدار أقدم
من OpenClaw يعتمد على الملفات:

```bash
openclaw doctor --session-sqlite restore --session-sqlite-all-agents
```

يترك الترحيل ملفات `sessions.json` القديمة في مكانها لأغراض الدعم
والتراجع، لكن ملفات JSONL النشطة للسجل النصي التي استوردت إلى SQLite
تُعاد تسميتها إلى `session-sqlite-import-archive/`. تتبع أوقات التشغيل الأقدم المعتمدة على الملفات
مسارات `sessionFile` في `sessions.json`، ولذلك تحتاج إلى استعادة هذه العناصر
قبل بدء التشغيل. تستخدم الاستعادة بيانات توصيف الترحيل، وتنقل فقط العناصر المؤرشفة
المسجلة التي تكون مساراتها الأصلية مفقودة، وتترك قاعدة بيانات SQLite
في مكانها للاسترداد اللاحق.

الجلسات المنشأة بعد الانتقال إلى SQLite موجودة في SQLite فقط ولن تظهر لوقت تشغيل
أقدم يعتمد على الملفات. إذا أجريت ترقية مجددًا بعد الرجوع إلى إصدار أقدم، فشغّل تسلسل فحص
Doctor والتحقق مجددًا حتى يتمكن OpenClaw من التحقق من العناصر القديمة
المستعادة قبل استيرادها.

## جلسات Cron وسجلات التشغيل

تنشئ عمليات cron المعزولة إدخالات جلسات/سجلات نصية خاصة بها مع مدة احتفاظ مخصصة:

- ينقّح `cron.sessionRetention` (الافتراضي `"24h"`) جلسات تشغيل cron المعزولة القديمة من المخزن؛ ويعطّله `false`.
- يحتفظ سجل التشغيل بأحدث 2000 صف نهائي لكل مهمة cron. تحتفظ الصفوف المفقودة بنافذة التنظيف البالغة 24 ساعة.

عندما ينشئ cron جلسة تشغيل معزولة جديدة قسرًا، فإنه ينقح إدخال الجلسة السابق `cron:<jobId>` قبل كتابة الصف الجديد: فهو ينقل التفضيلات الآمنة (إعدادات التفكير/السرعة/الإسهاب/الاستدلال، والتسميات، واسم العرض) وتجاوزات النموذج/المصادقة التي حددها المستخدم صراحة، لكنه يسقط سياق المحادثة المحيط (توجيه القناة/المجموعة، وسياسة الإرسال/قائمة الانتظار، ورفع الصلاحيات، والأصل، وارتباط وقت تشغيل ACP) حتى لا يرث تشغيل معزول جديد صلاحية تسليم أو وقت تشغيل قديمة من تشغيل أقدم.

## مفاتيح الجلسات (`sessionKey`)

يحدد `sessionKey` حاوية المحادثة التي توجد فيها (التوجيه + العزل). القواعد المعيارية: [/concepts/session](/ar/concepts/session).

| النمط                      | المثال                                                     |
| ---------------------------- | ----------------------------------------------------------- |
| الدردشة الرئيسية/المباشرة (لكل وكيل) | `agent:<agentId>:<mainKey>` (الافتراضي `main`)                |
| المجموعة                        | `agent:<agentId>:<channel>:group:<id>`                      |
| الغرفة/القناة (Discord/Slack) | `agent:<agentId>:<channel>:channel:<id>` أو `...:room:<id>` |
| Cron                         | `cron:<job.id>`                                             |
| Webhook                      | `hook:<uuid>` (ما لم يتم تجاوزه)                           |

## معرّفات الجلسات (`sessionId`)

يشير كل `sessionKey` إلى `sessionId` حالي (هوية سجل SQLite النصي التي تواصل المحادثة). يوجد منطق القرار في `initSessionState()` ضمن `src/auto-reply/reply/session.ts`.

- **إعادة الضبط** (`/new`، `/reset`) تنشئ `sessionId` جديدة لذلك `sessionKey`.
- **إعادة الضبط اليومية** (الافتراضي الساعة 4:00 صباحًا بالتوقيت المحلي على مضيف Gateway) تنشئ `sessionId` جديدة عند أول رسالة بعد حد إعادة الضبط.
- **انتهاء الصلاحية بسبب الخمول** (`session.reset.idleMinutes`، أو `session.idleMinutes` القديم) ينشئ `sessionId` جديدة عند وصول رسالة بعد نافذة الخمول. إذا جرى إعداد كلٍّ من الإعداد اليومي وإعداد الخمول، فتكون الأولوية لما تنتهي صلاحيته أولًا.
- **استئناف إعادة اتصال واجهة التحكم** يحافظ على الجلسة الظاهرة حاليًا لعملية إرسال واحدة بعد إعادة الاتصال عندما يتلقى Gateway قيمة `sessionId` المطابقة من عميل واجهة مستخدم للمشغّل. هذه إشارة لمرة واحدة؛ أما عمليات الإرسال القديمة العادية فلا تزال تنشئ `sessionId` جديدة.
- **أحداث النظام** (Heartbeat، وتنبيهات Cron، وإشعارات exec، ومسك دفاتر Gateway) قد تعدّل صف الجلسة، لكنها لا تمدّد مطلقًا حداثة إعادة الضبط اليومية أو الناتجة عن الخمول. يتخلص الانتقال عند إعادة الضبط من إشعارات أحداث النظام الموضوعة في قائمة الانتظار للجلسة السابقة قبل إنشاء الموجّه الجديد.
- **سياسة تفريع الأصل** تستخدم الفرع النشط في OpenClaw عند إنشاء تفريع لسلسلة محادثة أو لوكيل فرعي. إذا كان ذلك الفرع كبيرًا جدًا (أكثر من حد داخلي ثابت، يبلغ حاليًا 100K رمز)، يبدأ OpenClaw الفرع الابن بسياق معزول بدلًا من الفشل أو وراثة سجل غير قابل للاستخدام. يُحدَّد الحجم تلقائيًا ولا يمكن إعداده؛ ويزيل `openclaw doctor --fix` إعداد `session.parentForkMaxTokens` القديم.
- **تفريعات المشغّل**: ينشئ `sessions.create { parentSessionKey, fork: true }` جلسة جديدة يتفرع نصها من الحالة الحالية للجلسة الأصلية (باستخدام آلية التفريع نفسها المستخدمة عند إنشاء الوكلاء الفرعيين، بما في ذلك حد الحجم أعلاه). يُرفض التفريع أثناء وجود تشغيل نشط في الجلسة الأصلية، ويرث اختيار النموذج منها ما لم يُمرَّر نموذج صراحةً، ويضع علامة `forkedFromParent` على الجلسة الابنة مع عدادات رموز جديدة.

## مخطط مخزن الجلسات

يحتفظ مخزن وقت التشغيل بقيم `SessionEntry` في SQLite خاص بكل وكيل. نوع القيمة هو `SessionEntry` في `src/config/sessions.ts`. الحقول الأساسية (القائمة غير شاملة):

- `sessionId`: معرّف النص الحالي المستخدم لمخاطبة صفوف النص في SQLite
- `sessionStartedAt`: الطابع الزمني لبدء `sessionId` الحالية؛ تعتمد عليه حداثة إعادة الضبط اليومية. قد تستمد الصفوف القديمة هذه القيمة من ترويسة جلسة JSONL.
- `lastInteractionAt`: الطابع الزمني لآخر تفاعل حقيقي للمستخدم أو القناة؛ تعتمد عليه حداثة إعادة الضبط بسبب الخمول، كي لا تُبقي أحداث Heartbeat وCron وexec الجلسات نشطة. تعود الصفوف القديمة التي لا تحتوي هذا الحقل إلى وقت بدء الجلسة المستعاد.
- `updatedAt`: الطابع الزمني لآخر تعديل لصف المخزن، ويُستخدم للإدراج والتنقية ومسك الدفاتر، وليس المرجع المعتمد لحداثة إعادة الضبط اليومية أو بسبب الخمول.
- `archivedAt`: طابع زمني اختياري للأرشفة. تبقى الجلسات المؤرشفة في المخزن ونصوصها سليمة، وتُستبعد من قوائم الجلسات النشطة العادية.
- `pinnedAt`: طابع زمني اختياري للتثبيت. تُرتَّب الجلسات النشطة المثبتة قبل الجلسات غير المثبتة؛ وتؤدي أرشفة جلسة إلى إلغاء تثبيتها.
- التشغيل البيني مع سلاسل Codex: يتبع كلا الحقلين بنية إدارة السلاسل في Codex؛ إذ تُشتق القيمتان المنطقيتان `archived`/`pinned` المنقولتان عبر الاتصال دائمًا من الطابع الزمني وتُسجّلان على جانب الخادم، بما يطابق دلالات `threads.archived_at` في Codex وتسلسل camelCase. تستخدم طوابع OpenClaw الزمنية أجزاء الألف من الثانية منذ الحقبة، بينما يستخدم Codex الثواني منذ الحقبة، لذا تُجري الجسور التحويل عند حد Plugin الخاص بـ `codex`. لا يوفّر Codex واجهة API للتثبيت بعد (`thread/archive`/`thread/unarchive` فقط)؛ لذلك تبقى حالة التثبيت في جانب OpenClaw حتى تتوفر واجهة كهذه، وعندها تتيح البنية المطابقة للجلسات المرتبطة إجراء رحلة ذهاب وإياب لحالة التثبيت آليًا.
- لا تعرض مراقبة Codex إلا السلاسل الأصلية غير المؤرشفة. لا يمكن أرشفة سلسلة `idle` محلية في Gateway أو سلسلة `notLoaded` ذات نشاط مجهول عبر `thread/archive` الأصلي إلا بعد أن يؤكد المشغّل صراحةً عدم امتلاك أي عملية Codex أخرى لها؛ ويُجري Plugin أولًا قراءة جديدة للحالة المحلية للعملية، ثم تختفي السلسلة من الكتالوج. لا يمكن لتلك القراءة إثبات أن عملية App Server أخرى لا تستخدم السلسلة. يرفض OpenClaw أرشفة الصفوف النشطة وصفوف الأخطاء، ولا تتوفر أرشفة العقدة المقترنة حتى يتمكن جسر العقدة من امتلاك دورة حياة السلسلة المتدفقة بالكامل. تؤدي إزالة الأرشفة في عميل Codex أصلي إلى جعل السلسلة مؤهلة للظهور مجددًا.
- `lastReadAt` / `markedUnreadAt`: طوابع زمنية لحالة القراءة يسجلها `sessions.patch { unread }` على جانب الخادم؛ يسجل `unread: false` عملية قراءة (يضبط `lastReadAt` ويمسح `markedUnreadAt`)؛ ويضع `unread: true` علامة غير مقروءة على الجلسة حتى القراءة التالية. تعرض صفوف الجلسات قيمة منطقية مشتقة باسم `unread`: إما أنها محددة صراحةً كغير مقروءة، أو أن قراءتها سبقت أحدث نشاط. تبقى الجلسات التي لم تُحدَّد كمقروءة قط `unread: false`، حتى لا تظهر مؤشرات جديدة في عمليات التثبيت الحالية عند الترقية.
- `lastActivityAt`: الطابع الزمني لآخر تشغيل مكتمل للوكيل يُحتسب نشاطًا يستحق وضع علامة غير مقروء (تشغيلات المستخدم والقناة وCron). لا تحدّثه دورات Heartbeat والأحداث الداخلية ولا تصحيحات البيانات الوصفية؛ ولا تُعد `updatedAt` إشارة نشاط.
- `sessionFile`: علامة قديمة محتفظ بها للتوافق مع الترحيل والأرشفة؛ يستخدم وقت التشغيل النشط هوية SQLite
- `chatType`: `direct | group | room`
- `provider`، `subject`، `room`، `space`، `displayName`: بيانات وصفية لتسمية المجموعة أو القناة
- خيارات التبديل: `thinkingLevel`، `verboseLevel`، `reasoningLevel`، `elevatedLevel`، `sendPolicy` (تجاوز خاص بكل جلسة)
- اختيار النموذج: `providerOverride`، `modelOverride`، `authProfileOverride`
- عدادات الرموز (وفق أفضل تقدير وتعتمد على المزوّد): `inputTokens`، `outputTokens`، `totalTokens`، `contextTokens`
- `compactionCount`: عدد مرات اكتمال Compaction التلقائي لمفتاح الجلسة هذا
- `memoryFlushAt` / `memoryFlushCompactionCount`: الطابع الزمني وعدد عمليات Compaction لآخر تفريغ للذاكرة قبل Compaction

Gateway هو المرجع المعتمد: وقد يعيد كتابة الإدخالات أو تعبئتها أثناء
تشغيل الجلسات. بالنسبة إلى عمليات التثبيت القديمة المعتمدة على الملفات، رحّل باستخدام
`openclaw doctor --session-sqlite import --session-sqlite-all-agents` بدلًا من
تعديل `sessions.json` وتوقّع استمرار وقت التشغيل في قراءة ذلك الملف.

## بنية أحداث النص

يدير موصّل جلسات OpenClaw النصوص ويعرضها لرمز وقت التشغيل عبر أدوات مساعدة قائمة على الهوية. تدفق الأحداث للإلحاق فقط:

- الإدخال الأول: ترويسة الجلسة - `type: "session"`، `id`، `cwd`، `timestamp`، و`parentSession` اختياري.
- ثم: إدخالات تحتوي `id` + `parentId` (بنية شجرية).

أنواع الإدخالات الجديرة بالملاحظة:

- `message`: رسائل المستخدم والمساعد وtoolResult
- `custom_message`: رسالة يحقنها الامتداد وتدخل _بالفعل_ في سياق النموذج (تُعرض في TUI عندما تكون `display: true`، وتُخفى بالكامل عندما تكون `display: false`)
- `custom`: حالة امتداد لا تدخل في سياق النموذج (لاستمرار حالة الامتداد عبر عمليات إعادة التحميل)
- `compaction`: ملخص Compaction مستمر يحتوي `firstKeptEntryId` و`tokensBefore`
- `branch_summary`: ملخص مستمر عند التنقل في فرع شجري

لا يُجري OpenClaw عمدًا «تصحيحًا» للنصوص؛ إذ يستخدم Gateway ‏`SessionManager` لقراءتها وكتابتها.

## نوافذ السياق مقابل الرموز المتتبعة

مفهومان مختلفان:

1. **نافذة سياق النموذج**: حد أقصى صارم لكل نموذج (الرموز المرئية للنموذج). تأتي من كتالوج النماذج ويمكن تجاوزها عبر الإعداد.
2. **عدادات مخزن الجلسة**: إحصاءات متجددة تُكتب في صف الجلسة (تُستخدم في `/status` ولوحات المعلومات). تمثل `contextTokens` قيمة تقديرية أو تقريرية في وقت التشغيل؛ فلا تتعامل معها كضمان صارم.

المزيد عن الحدود: [/reference/token-use](/ar/reference/token-use).

## Compaction: ماهيته

يلخّص Compaction المحادثة الأقدم في إدخال `compaction` مستمر ضمن النص، مع إبقاء الرسائل الحديثة سليمة. بعد Compaction، ترى الدورات اللاحقة ملخص Compaction إضافةً إلى الرسائل اللاحقة لـ `firstKeptEntryId`. يُعد Compaction **مستمرًا**، بخلاف تنقية الجلسة؛ راجع [/concepts/session-pruning](/ar/concepts/session-pruning).

تكون إعادة حقن قسم AGENTS.md بعد Compaction اختيارية عبر `agents.defaults.compaction.postCompactionSections`؛ وعندما تكون غير مضبوطة أو تكون `[]`، لا يضيف OpenClaw مقتطفات AGENTS.md فوق ملخص Compaction.

### حدود الأجزاء واقتران الأدوات

عند تقسيم نص طويل إلى أجزاء Compaction، يُبقي OpenClaw استدعاءات أدوات المساعد مقترنة بإدخالات `toolResult` المطابقة لها:

- إذا كان التقسيم حسب حصة الرموز سيقع بين استدعاء أداة ونتيجته، ينقل OpenClaw الحد إلى رسالة استدعاء الأداة الخاصة بالمساعد بدلًا من فصل الزوج.
- إذا كانت كتلة نتائج أدوات في النهاية ستتسبب لولا ذلك في تجاوز الجزء للحجم المستهدف، يحافظ OpenClaw على كتلة الأدوات المعلّقة هذه ويبقي الذيل غير الملخّص سليمًا.
- لا تُبقي كتل استدعاءات الأدوات الملغاة أو الخاطئة تقسيمًا معلّقًا مفتوحًا.

## متى يحدث Compaction التلقائي

مشغّلان في وكيل OpenClaw المضمّن:

1. **الاسترداد من التجاوز**: يعيد النموذج خطأ تجاوز السياق (`request_too_large`، `context length exceeded`، `input exceeds the maximum number of tokens`، `input token count exceeds the maximum number of input tokens`، `input is too long for the model`، `ollama error: context length exceeded`، ومتغيرات أخرى وفق بنية المزوّد)؛ يُجرى Compaction ثم تُعاد المحاولة. عندما يبلّغ المزوّد عن عدد الرموز التي جرت محاولة استخدامها، يمرر OpenClaw ذلك العدد المرصود إلى Compaction الخاص بالاسترداد من التجاوز؛ وإذا أكد المزوّد حدوث التجاوز لكنه لم يعرض عددًا قابلًا للتحليل، يمرر OpenClaw عددًا اصطناعيًا يتجاوز الميزانية بالحد الأدنى إلى محركات Compaction وأدوات التشخيص. إذا ظل الاسترداد من التجاوز يفشل، يعرض OpenClaw إرشادات صريحة ويحافظ على تعيين الجلسة الحالي بدلًا من الانتقال بصمت إلى معرّف جلسة جديد؛ أعد محاولة إرسال الرسالة، أو شغّل `/compact`، أو شغّل `/new`.
2. **صيانة الحد**: بعد دورة ناجحة، عندما `contextTokens > contextWindow - reserveTokens`، حيث تمثل `contextWindow` نافذة سياق النموذج وتمثل `reserveTokens` هامشًا محجوزًا للموجّهات إضافةً إلى إخراج النموذج التالي.

يعمل حارسان إضافيان خارج هذين المشغّلين:

- **Compaction المحلي السابق للتشغيل**: اضبط `agents.defaults.compaction.maxActiveTranscriptBytes` (بوحدات البايت أو كسلسلة مثل `"20mb"`) لتشغيل Compaction محلي قبل فتح التشغيل التالي بمجرد بلوغ النص النشط ذلك الحجم. هذا حارس حجم لتكلفة إعادة الفتح المحلية، وليس أرشفة خامًا؛ إذ يظل Compaction الدلالي العادي يعمل، ويتطلب `truncateAfterCompaction` حتى يصبح الملخص المضغوط نصًا لاحقًا جديدًا.
- **الفحص المسبق في منتصف الدورة**: اضبط `agents.defaults.compaction.midTurnPrecheck.enabled: true` (القيمة الافتراضية `false`) لإضافة حارس لحلقة الأدوات. بعد إلحاق نتيجة أداة وقبل استدعاء النموذج التالي، يقدّر OpenClaw ضغط الموجّه باستخدام منطق ميزانية الفحص السابق للتشغيل نفسه المستخدم عند بدء الدورة. إذا لم يعد السياق ملائمًا، فلا ينفّذ الحارس Compaction ضمنيًا؛ بل يطلق إشارة فحص مسبق منظّمة في منتصف الدورة، ويوقف إرسال الموجّه الحالي، ويتيح لحلقة التشغيل الخارجية استخدام مسار الاسترداد الحالي (اقتطاع نتائج الأدوات كبيرة الحجم عندما يكون ذلك كافيًا، أو تشغيل وضع Compaction المُعدّ وإعادة المحاولة). يعمل مع وضعي Compaction ‏`default` و`safeguard`، بما في ذلك Compaction الوقائي المدعوم من المزوّد. وهو مستقل عن `maxActiveTranscriptBytes`: يعمل حارس الحجم بالبايت قبل فتح الدورة، بينما يعمل الفحص المسبق في منتصف الدورة لاحقًا، بعد إلحاق نتائج أدوات جديدة.

## إعدادات Compaction

```json5
{
  agents: {
    defaults: {
      compaction: {
        enabled: true,
        reserveTokens: 16384,
        keepRecentTokens: 20000,
      },
    },
  },
}
```

يفرض OpenClaw أيضًا حدًا أدنى للسلامة لعمليات التشغيل المضمّنة: إذا كانت `compaction.reserveTokens` أقل من `reserveTokensFloor` (القيمة الافتراضية `20000`)، يرفعها OpenClaw إلى ذلك الحد. اضبط `agents.defaults.compaction.reserveTokensFloor: 0` لتعطيل الحد الأدنى. عندما تكون نافذة سياق النموذج النشط معروفة، يُقيَّد كل من الحد الأدنى والاحتياطي الفعلي النهائي بحيث لا يمكن للاحتياطي استهلاك ميزانية الموجّه بالكامل. يمنع هذا النماذج ذات السياق الصغير (مثل نموذج محلي بسعة 16K رمز) من الدخول في Compaction منذ الرمز الأول؛ ومن دون نافذة سياق معروفة، تظل ميزانيات الاحتياطي المضبوطة والحالية غير مقيّدة. سبب وجود حد أدنى أصلًا: ترك هامش كافٍ لمهام «الصيانة» متعددة الأدوار (مثل تفريغ الذاكرة الموضح أدناه) قبل أن يصبح Compaction حتميًا. التنفيذ: `applyAgentCompactionSettingsFromConfig()` في `src/agents/agent-settings.ts`، ويُستدعى من مسارات إعداد دور المشغّل المضمّن وCompaction.

يحترم `/compact` اليدوي قيمة `agents.defaults.compaction.keepRecentTokens` الصريحة ويحافظ على نقطة اقتطاع الذيل الحديث الخاصة ببيئة التشغيل. من دون ميزانية احتفاظ صريحة، يكون Compaction اليدوي نقطة تحقق صارمة، ويبدأ السياق المعاد بناؤه من الملخص الجديد.

عند تمكين `truncateAfterCompaction`، يدوّر OpenClaw النسخة النصية النشطة إلى نسخة لاحقة خضعت لـCompaction بعد اكتماله. تستخدم إجراءات نقاط تحقق التفرع/الاستعادة تلك النسخة اللاحقة؛ وتظل ملفات نقاط التحقق القديمة السابقة لـCompaction قابلة للقراءة ما دامت مُشارًا إليها.

## موفّرو Compaction القابلون للتوصيل

تسجّل Plugins موفّر Compaction عبر `registerCompactionProvider()` في واجهة API الخاصة بالـPlugin. عندما تُضبط `agents.defaults.compaction.provider` على معرّف موفّر مسجّل، يفوّض امتداد الحماية التلخيص إلى ذلك الموفّر بدلًا من مسار `summarizeInStages` المدمج.

- `provider`: معرّف Plugin مسجّل لموفّر Compaction. اتركه من دون ضبط لاستخدام تلخيص LLM الافتراضي. يؤدي ضبط `provider` إلى فرض `mode: "safeguard"`.
- يتلقى الموفّرون تعليمات Compaction وسياسة الحفاظ على المعرّفات نفسها التي يتلقاها المسار المدمج، وتظل آلية الحماية تحافظ على سياق لاحقة الأدوار الحديثة والأدوار المجزأة بعد مخرجات الموفّر.
- يعيد تلخيص الحماية المدمج استخلاص الملخصات السابقة مع الرسائل الجديدة بدلًا من الاحتفاظ بالملخص السابق كاملًا كما هو.
- يمكّن وضع الحماية تدقيقات جودة الملخص افتراضيًا؛ اضبط `qualityGuard.enabled: false` لتخطي سلوك إعادة المحاولة عند وجود مخرجات مشوّهة.
- إذا فشل الموفّر أو أعاد نتيجة فارغة، يعود OpenClaw تلقائيًا إلى تلخيص LLM المدمج. تُعاد إشارات الإلغاء/انتهاء المهلة التي شغّلها المستدعي صراحةً بدلًا من ابتلاعها، بحيث يُحترم الإلغاء دائمًا.

المصدر: `src/plugins/compaction-provider.ts`، `src/agents/agent-hooks/compaction-safeguard.ts`.

## الأسطح المرئية للمستخدم

- `/status` في أي جلسة محادثة
- `openclaw status` ‏(CLI)
- `openclaw sessions` / `openclaw sessions --json`
- سجلات Gateway ‏(`pnpm gateway:watch` أو `openclaw logs --follow`): ‏`embedded run auto-compaction start` + `complete`
- الوضع التفصيلي: `🧹 Auto-compaction complete` بالإضافة إلى عدد عمليات Compaction

## الصيانة الصامتة (`NO_REPLY`)

يدعم OpenClaw أدوارًا «صامتة» لمهام الخلفية التي ينبغي ألا يرى المستخدم مخرجاتها الوسيطة.

- يبدأ المساعد مخرجاته برمز الصمت الدقيق `NO_REPLY` / `no_reply` للدلالة على «عدم تسليم رد إلى المستخدم». يزيل OpenClaw هذا الرمز أو يمنعه في طبقة التسليم.
- منع رمز الصمت الدقيق غير حساس لحالة الأحرف: تُحتسب كل من `NO_REPLY` و`no_reply` عندما تكون الحمولة بأكملها مجرد رمز الصمت.
- اعتبارًا من `2026.1.10`، يمنع OpenClaw أيضًا بث المسودة/الكتابة عندما تبدأ كتلة جزئية بـ`NO_REPLY`، كي لا تسرّب العمليات الصامتة مخرجات جزئية في منتصف الدور.
- هذا مخصص فقط لأدوار الخلفية الحقيقية التي لا تتضمن تسليمًا، وليس اختصارًا لطلبات المستخدم العادية القابلة للتنفيذ.

## تفريغ الذاكرة قبل Compaction

قبل حدوث Compaction التلقائي، يمكن لـOpenClaw تشغيل دور وكيلي صامت يكتب حالة دائمة على القرص (مثل `memory/YYYY-MM-DD.md` في مساحة عمل الوكيل) كي لا يتمكن Compaction من محو السياق الحرج. يراقب استخدام سياق الجلسة، وبمجرد تجاوزه عتبة مرنة أدنى من عتبة Compaction، يرسل توجيهًا صامتًا «اكتب الذاكرة الآن» باستخدام رمز الصمت الدقيق `NO_REPLY` / `no_reply` بحيث لا يرى المستخدم شيئًا.

الإعداد (`agents.defaults.compaction.memoryFlush`)، والمرجع الكامل في [/gateway/config-agents](/ar/gateway/config-agents#agentsdefaultscompaction):

| المفتاح                         | القيمة الافتراضية          | ملاحظات                                                                                                                                  |
| --------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `enabled`                   | `true`           |                                                                                                                                        |
| `model`                     | غير مضبوط            | تجاوز دقيق للموفّر/النموذج لدور التفريغ فقط، مثل `ollama/qwen3:8b`                                                   |
| `softThresholdTokens`       | `4000`           | الفجوة الواقعة دون عتبة Compaction التي تشغّل عملية التفريغ                                                                               |
| `forceFlushTranscriptBytes` | غير مضبوط (معطّل) | يفرض عملية تفريغ بمجرد بلوغ ملف النسخة النصية حجم البايتات هذا (أو سلسلة مثل `"2mb"`)، حتى إذا كانت عدادات الرموز قديمة؛ وتؤدي `0` إلى التعطيل |
| `prompt`                    | مدمج         | رسالة المستخدم لدور التفريغ                                                                                                        |
| `systemPrompt`              | مدمج         | موجّه نظام إضافي يُلحق بدور التفريغ                                                                                        |

ملاحظات:

- يتضمن الموجّه/موجّه النظام الافتراضي تلميح `NO_REPLY` لمنع التسليم.
- عند ضبط `model`، يستخدم دور التفريغ ذلك النموذج من دون وراثة سلسلة الاحتياط للجلسة النشطة، بحيث لا تعود صيانة محلية فقط بصمت إلى نموذج محادثة مدفوع عند الفشل.
- يعمل التفريغ مرة واحدة لكل دورة Compaction (ويُتتبّع ذلك في صف الجلسة).
- يعمل التفريغ فقط لجلسات OpenClaw المضمّنة؛ وتتخطاه خلفيات CLI وأدوار Heartbeat.
- يُتخطى التفريغ عندما تكون مساحة عمل الجلسة للقراءة فقط (`workspaceAccess: "ro"` أو `"none"`).
- راجع [الذاكرة](/ar/concepts/memory) لمعرفة تخطيط ملفات مساحة العمل وأنماط الكتابة.

يعرض OpenClaw خطاف `session_before_compact` في واجهة API الخاصة بالامتدادات، لكن منطق التفريغ أعلاه يوجد في جانب Gateway ‏(`src/auto-reply/reply/memory-flush.ts`، ‏`src/auto-reply/reply/agent-runner-memory.ts`) وليس في ذلك الخطاف.

## قائمة التحقق لاستكشاف الأخطاء وإصلاحها

- **هل مفتاح الجلسة خاطئ؟** ابدأ بـ[/concepts/session](/ar/concepts/session) وتأكد من `sessionKey` في `/status`.
- **هل يوجد عدم تطابق بين المخزن والنسخة النصية؟** تأكد من مضيف Gateway ومسار المخزن من `openclaw status`.
- **هل يتكرر Compaction بإفراط؟** تحقق من نافذة سياق النموذج (إذا كانت صغيرة جدًا فإنها تفرض Compaction متكررًا)، ومن `reserveTokens` (إذا كانت مرتفعة جدًا مقارنة بنافذة النموذج فإنها تؤدي إلى Compaction أبكر)، ومن تضخم نتائج الأدوات (اضبط تقليم الجلسة).
- **هل يبدو أن كل موجّه يتجاوز السعة في نموذج محلي صغير؟** تأكد من أن الموفّر يبلّغ عن نافذة سياق النموذج الصحيحة. لا يستطيع OpenClaw تقييد الاحتياطي الفعلي إلا عندما تكون تلك النافذة معروفة.
- **هل تتسرّب الأدوار الصامتة؟** تأكد من أن الرد يبدأ برمز الصمت الدقيق `NO_REPLY` (من دون حساسية لحالة الأحرف)، وأنك تستخدم إصدارًا يتضمن إصلاح منع البث (`2026.1.10`+).

## ذو صلة

- [إدارة الجلسات](/ar/concepts/session)
- [تقليم الجلسات](/ar/concepts/session-pruning)
- [محرك السياق](/ar/concepts/context-engine)
- [مرجع إعداد الوكيل](/ar/gateway/config-agents)
