> ## Documentation Index
> Fetch the complete documentation index at: https://lousho.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Agent Forge

Agent Forge (`apps/agent-forge`) هي لوحة التحكم المرئية المرافقة لهذه الـ SDK: تبني فيها الرسم البياني (graph) للوكيل على لوحة رسم (canvas)، وتشغّله، وتراقب تنفيذه في وحدة تصحيح حيّة (debug console)، وتحاوره، وتكتب خطّافات قبلية وبعدية تعمل في بيئة معزولة، وكل ذلك بقراءة وكتابة ملف `AgentSpec` بصيغة YAML نفسه الذي يستخدمه `lousho dev` و`lousho build`. تُشغَّل بأمر واحد هو `lousho studio`، وتأتي ضمن حزمة npm الخاصة بهذه الـ SDK (LOU-S).

يغطي هذا المستند: التثبيت، والبدء السريع مع `lousho studio`، وجولة لبناء أول وكيل، وكتابة الخطّافات، والسفر عبر الزمن (إعادة تشغيلٍ انطلاقًا من خطوة سابقة)، وكيف يعمل ربط الإعدادات والأسرار والنشر (وما الذي لا يعمل منه بعد).

## التثبيت

تأتي Agent Forge داخل `@lousho/build-ai-agent` نفسها، فلا توجد حزمة منفصلة تثبّتها:

```bash theme={null}
npm install @lousho/build-ai-agent
```

هذا كل شيء. يشغّل `lousho studio` (أدناه) نسخة مبنية مسبقًا من التطبيق؛ ولا تحتاج إلى الشيفرة المصدرية لـ `apps/agent-forge` ولا إلى اعتمادياتها التطويرية (Vite و`tsx` وغيرهما) كي تستخدمها.

أما إذا كنت تعمل داخل المستودع الأحادي (monorepo) لهذه الـ SDK نفسها (أي تساهم في Agent Forge ذاتها)، فانظر [وضع التطوير](#وضع-التطوير) أدناه.

## البدء السريع

```bash theme={null}
npx lousho studio
```

يشغّل هذا الأمر خادمًا محليًا واحدًا ويطبع عنوانه (الافتراضي `http://127.0.0.1:4750`). افتحه في المتصفح، فترى لوحة الرسم، والشريط الأيسر (وكلاؤك المحفوظون مع لوحة العُقد والخطّافات)، وInspector (على اليمين)، ودرجًا سفليًا فيه التبويبات Chat/Logs/Trace/Output/Settings.

خيارات مفيدة:

```bash theme={null}
npx lousho studio --port 5000       # pick a different port
npx lousho studio --host 0.0.0.0    # bind to all interfaces
npx lousho studio --prod            # force production mode (see below)
npx lousho studio --dev             # force dev mode (monorepo only)
```

تُخزَّن ملفات مواصفات الوكلاء وحالة التشغيل تحت `.lousho/` في المجلد الذي شغّلت منه `lousho studio` (ملفات YAML للوكلاء تحت `.lousho/agents/`، وبجوارها نقاط الحفظ والموافقات)، وهو تخطيط `.lousho/` نفسه الذي يستخدمه `lousho dev` و`lousho build`.

### وضع الإنتاج ووضع التطوير

للأمر `lousho studio` وضعان، وهو يختار المناسب منهما تلقائيًا:

* **الإنتاج** (الافتراضي بعد بناء Agent Forge): خادم Express واحد يقدّم واجهة REST/WebSocket البرمجية *و*العميل المبني مسبقًا (تطبيق React) كملفات ثابتة، على منفذ واحد. هذا ما يعمل حين تثبّت الحزمة المنشورة بـ `npm install`: لا خادم تطوير Vite منفصل ولا محمِّل TypeScript.
* **التطوير** (يُلجأ إليه إذا لم يُجرَ البناء بعد، أي داخل نسخة مصدرية من هذا المستودع الأحادي): يعمل خادم الواجهة البرمجية مباشرة من شيفرته المصدرية بلغة TypeScript عبر `tsx`، إلى جانب خادم تطوير Vite حقيقي (مع إعادة تحميل فوري للوحدات) يمرّر طلبات الواجهة البرمجية إليه. عمليتان، ومنفذان داخليًا، وأمر واحد.

يفرض `--prod` أو `--dev` أحد الوضعين؛ وإذا شغّلت `lousho studio` دون أي منهما اكتشف الوضع تلقائيًا بحسب وجود `apps/agent-forge/dist-server`.

## جولة بناء أول وكيل

1. **أنشئ وكيلًا.** في تبويب "Agents" في الشريط الأيسر، انقر **New**، وأعطِ الوكيل اسمًا، واختر قالب بداية. القالب **Blank graph** (عقدة LLM واحدة تستخدم المزوّد المدمج `mock`) هو أسرع طريقة للتجربة دون أي مفاتيح API. تنشئ Agent Forge الوكيل وتفتحه على لوحة الرسم.
2. **انظر إلى الرسم البياني.** الوكيل الفارغ عقدة `llm` واحدة. اسحب عُقدًا أخرى من لوحة العناصر في الشريط الأيسر (**Trigger** و**LLM step** و**Tool call** و**Approval gate** و**Response / output**) واربط بينها بالسحب بين مقابضها. انقر عقدة لتعديل إعداداتها (الموجّه، المزوّد/النموذج، الأدوات، نقاط التوقف) في Inspector على اليمين.
3. **شغّله.** انقر **Run** في الشريط العلوي. مع المزوّد `mock` لا شيء يحتاج إلى إعداد: فهو يعيد مخرجات جاهزة حتمية، وهذا هو المقصود تمامًا لتجربة بقية الواجهة دون الحاجة إلى مفتاح API لنموذج LLM حقيقي. يتابع مؤشر الحالة في الشريط العلوي التشغيلَ (`running` → `idle`/`error`/`awaiting approval`).
4. **راقبه في وحدة التصحيح.** افتح تبويب **Logs** في الدرج السفلي لترى سجلًا حيًّا قابلًا للتصفية لأحداث التشغيل (أحداث trigger/llm/tool/sandbox/checkpoint/approval)، أو تبويب **Trace** لترى مخططًا شلاليًا لمقاطع التتبّع (spans). فعّل **Debug** في الشريط العلوي (أو ضع نقطة توقف على عقدة في Inspector) لإيقاف التشغيل مؤقتًا عند حدود استدعاءات LLM والأدوات والتقدّم فيه خطوة خطوة بزرَّي **Step**/**Continue** في شريط التصحيح؛ ووسّع "Live message array" هناك لتفحص قائمة الرسائل الجارية. يعرض تبويب **Output** كائن `ExecutionResult` كاملًا (الرسائل، استدعاءات الأدوات، الاستهلاك، الخطوات) على هيئة شجرة JSON قابلة للطي عند انتهاء التشغيل أو توقفه مؤقتًا.
5. **حاوره.** تبويب **Chat** قناة محادثة مستقلة (`POST /agents/:id/message`، ويُبَث الرد عبر اتصال WebSocket نفسه المستخدم لكل شيء آخر): أرسل إليه رسالة فيرد في المحادثة، بمعزل عن زر "Run" الخاص بالرسم البياني أعلاه. يحتفظ كل وكيل بسجل محادثاته الخاص (يبدأ `+ New chat` جلسة جديدة؛ وتبقى الجلسات القديمة قابلة للتصفح).
6. **وافق على استدعاء أداة متوقف.** أضف عقدة **Tool call**، وافتحها في Inspector، واختر أداة. بعض الأدوات (أو سياسة الوكيل نفسه) قد تشترط موافقة بشرية قبل التنفيذ. حين يصل تشغيل أو محادثة إلى أداة كهذه، تظهر بطاقة موافقة مضمّنة (في الشريط العلوي لتشغيل الرسم البياني، أو كفقاعة رسالة في محادثة Chat) تعرض اسم الأداة ووسائطها. انقر **Approve** للسماح بالمتابعة أو **Reject** لإلغاء ذلك الاستدعاء؛ ويُستأنف التشغيل تلقائيًا في الحالتين.

## الخطّافات

الخطّافات (hooks) (LOU-Q) دوال صغيرة تعمل في بيئة معزولة، وتُنفَّذ مباشرة قبل استدعاء أداة أو استدعاء `generate` لنموذج LLM أو بعده. هي الآلية نفسها التي يوفّرها قلب الـ SDK باسم `HookRegistry`/`AgentHook` (انظر [نظرة عامة على الواجهة البرمجية](/ar/api-overview))، لكنها هنا تُكتب مرئيًا وتُرفق بعقدة محددة على لوحة الرسم.

لإرفاق خطّاف:

1. اختر عقدة `llm` أو `tool` على لوحة الرسم (لا تنطبق الخطّافات إلا على هاتين، فهما النقطتان اللتان يستدعي عندهما `AgentExecutor` الخارج فعلًا).
2. افتح قسم **Hooks** في Inspector. اسحب عنصر **Pre-hook** أو **Post-hook** من لوحة العناصر في الشريط الأيسر إلى العقدة (أو أفلته مباشرة في قسم Hooks) لإرفاق خطّاف جديد؛ وستُعرض عليك قوالب بداية (`redact-pii` و`rate-limit` و`audit-log` و`inject-context`) تتخذها نقطة انطلاق قابلة للتعديل.
3. انقر شارة الخطّاف لاختياره، ثم عدّل شيفرته في محرر CodeMirror. الشيفرة هي **جسم** دالة غير متزامنة تُستدعى بالشكل `hook(ctx)` داخل عملية فرعية معزولة (`server/hookSandbox.ts`)، وليس في المتصفح ولا في عملية خادم الواجهة البرمجية نفسها أبدًا:
   * في خطّاف استدعاء الأداة، يكون `ctx` هو `{ toolName, args, result?, error? }`. يستطيع الخطّاف القبلي تعديل `ctx.args`؛ ويستطيع الخطّاف البعدي فحص `ctx.result`/`ctx.error` أو تعديلهما. أعِد `ctx`.
   * في خطّاف توليد LLM، يكون `ctx` هو `{ messages, model }`. عدّل `ctx.messages` أو أضف إليها ثم أعِد `ctx`.
   * **رمي استثناء يلغي الخطوة**: خطّاف تحديد المعدّل مثلًا يرمي استثناءً ليمنع استدعاء الأداة تمامًا بدل أن يتركه يُنفَّذ.
4. بدّل المفتاح على شارة الخطّاف لتفعيله أو تعطيله دون إزالته، أو استخدم زر **x** لإزالته كليًا. الخطّافات المفعّلة وحدها تُصرَّف ضمن التشغيل.

مثال: خطّاف قبلي لحجب البيانات الشخصية (PII) على عقدة أداة (وهو قالب البداية `redact-pii`):

```js theme={null}
const PII = /[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/gi;
for (const key of Object.keys(ctx.args || {})) {
  if (typeof ctx.args[key] === 'string') {
    ctx.args[key] = ctx.args[key].replace(PII, '[REDACTED]');
  }
}
return ctx;
```

حفظ الوكيل يخزّن هذه الخطّافات في `spec.policy.hooks` ضمن ملف YAML الخاص بالوكيل؛ ويصرّف الخادم الخطّافات المفعّلة إلى `HookRegistry` حقيقي للتشغيل (`server/compileHooks.ts`)، وتمر عبر `SandboxAdapter` نفسه الذي تستخدمه الأداة المعزولة.

## السفر عبر الزمن

تحتفظ Agent Forge بنقاط الحفظ (checkpoints) كلها لكل تشغيل، لا بالأخيرة فقط: فمخزنها الملفي (`server/checkpointStore.ts`) يحتفظ بالسجل المحدود نفسه الذي يحتفظ به `LocalStorageCheckpointStore` في الـ SDK (أحدث 50 عملية حفظ لكل تشغيل، تحت `.lousho/agents/<id>/checkpoint-history/`؛ انظر [سجل نقاط الحفظ](/ar/durable-execution#السجل-التاريخي-لنقاط-الحفظ)). ومن هذا السجل تستطيع تفريع تشغيل عند أي خطوة، وتغيير ما جرى فيها، وإعادة تشغيله بجوار الأصل، ويتولى العمل [`AgentExecutor.fork()`](/ar/durable-execution#التفريع-وإعادة-التشغيل) و`compareTrajectories()`.

### تبويب History

1. شغّل الوكيل (زر **Run** في الشريط العلوي، أو رسالة في Chat).
2. افتح تبويب **History** في الدرج السفلي. يسرد خطوات التشغيل: رقم الخطوة، والحالة، وسبب انتهاء النموذج، واستدعاءات الأدوات التي جرت، وعدد الرموز (tokens) وتكلفة استدعاء النموذج في الخطوة عند توفّرهما.
3. انقر **Edit and replay from here** على إحدى الخطوات. اختر **Append a user message** واكتب رسالة، أو اختر أحد استدعاءات الأدوات في الخطوة لتعديل نتيجته (يُملأ الحقل مسبقًا بالنتيجة المسجَّلة؛ والنص الذي يصح تحليله كـ JSON يُرسَل كـ JSON).
4. انقر **Fork and replay**. يُفرَّع التشغيل عند تلك الخطوة مع تعديلك ويبدأ كتشغيل جديد باسم `<id>.fork-<n>`.
5. يُفتح الفرع بجوار الأصل في عرض لمسارَي التنفيذ جنبًا إلى جنب: كل دورة نموذج في التشغيلين (النص، واستدعاءات الأدوات ونتائجها)، مع إبراز أول دورة يختلفان فيها بوسم **diverged**، وتحتها عناصر الانحراف (ترتيب الأدوات، الوسائط، عدد الخطوات، سبب الانتهاء). ويُحدَّث العرض عند انتهاء الفرع.

### المسارات

معرّف التشغيل هو معرّف جلسة نقاط الحفظ الخاصة به: معرّف الوكيل لتشغيلات الوكيل نفسه، و`<id>.fork-<n>` لفرع من التشغيل `<id>`. لدى خادم التحكم في وقت التشغيل ثلاثة مسارات له (يستخدمها تبويب History):

| المسار | ما يفعله |
| - | - |
| `GET /runs/:id/history` | `{ runId, steps }`: مدخل واحد لكل خطوة من أحدث تنفيذ للتشغيل (أحدث نقطة حفظ حُفظت عند تلك الخطوة)، من الأقدم إلى الأحدث، مع `status` و`savedAt` و`finishReason` و`toolCalls` (`{ id, name, args, result? }`)، و`tokens` / `costUsd` لاستدعاء النموذج في الخطوة عند توفّرهما. يعيد 404 حين لا تكون للتشغيل نقاط حفظ. |
| `POST /runs/:id/fork` | الجسم `{ fromStep, patch? }`، حيث `patch` هو `{ toolResult?: { toolCallId, result }, appendInput?, businessState? }`. يفرّع التشغيل عند `fromStep`، ثم يبدأ الفرع عبر سجل التشغيلات بملف مواصفات التشغيل الأصلي. يعيد 202 مع `{ runId, fromStep, status }`؛ ويُبَث الفرع على `WS /agents/<runId>/stream` ويُبلَّغ عن حالته على `GET /agents/<runId>/status` كأي تشغيل. يعيد 400 لجسم غير صالح أو `toolCallId` غير معروف، و404 لتشغيل غير معروف أو خطوة بلا نقطة حفظ. |
| `GET /runs/compare?a=&b=` | ناتج `compareTrajectories(a, b)` لأحدث نقطتَي حفظ لتشغيلين: دورات النموذج لكل تشغيل، و`divergedAt` (أول دورة تختلف) وعناصر `drift`. يعيد 404 حين لا تكون لأحد التشغيلين نقطة حفظ. |

تسلسل العمل، لوكيل اسمه `weather` شُغِّل مرة واحدة:

```bash theme={null}
curl localhost:4750/runs/weather/history
# {"runId":"weather","steps":[{"step":1,"status":"finished","finishReason":"stop","toolCalls":[],"tokens":...}]}

curl -X POST localhost:4750/runs/weather/fork -H 'content-type: application/json' \
  -d '{"fromStep":1,"patch":{"appendInput":"And in Celsius?"}}'
# {"runId":"weather.fork-1","fromStep":1,"status":{"status":"running",...}}

curl 'localhost:4750/runs/compare?a=weather&b=weather.fork-1'
# {"a":[...],"b":[...],"divergedAt":2,"drift":[{"field":"steps","committed":"1","current":"2"}]}
```

الفرع تشغيل قائم بذاته: نقاط حفظ التشغيل الأصلي وحالته ومحادثته تبقى دون تغيير.

## الإعدادات والأسرار وربط النشر

في الدرج السفلي تبويب **Settings** من ثلاثة أجزاء: مفاتيح API للمزوّدين (OpenAI وAnthropic، تُخزَّن مشفّرة تحت `.lousho/` ولا تُعرض مرة أخرى أبدًا)، وملفات إعدادات مسمّاة (المزوّد، مهايئ النشر، مهلة الخطّاف، مفتاح تفعيل OpenTelemetry؛ وتُحفظ في `.lousho/settings.json` الذي لا يحوي أسرارًا)، وقسم **Deploy** يختار مهايئًا (`node-server` أو `docker` أو `cloudflare-worker`) ويشغّل `lousho build` للوكيل المحدد. أما بقية المزوّدين فما زالوا يقرؤون متغيرات البيئة الخاصة بهم، كما يفعل `lousho dev` و`lousho build` (انظر [الإعداد](/ar/configuration))، والمزوّد `mock` لا يحتاج إلى بيانات اعتماد.

## وضع التطوير

إذا كنت تعمل داخل المستودع الأحادي لهذه الـ SDK نفسها (تساهم في Agent Forge ذاتها، لا تستخدمها فحسب)، فإن `lousho studio` ينتقل إلى وضع التطوير تلقائيًا ما دام `apps/agent-forge/dist-server` لم يُبنَ بعد:

```bash theme={null}
git clone https://github.com/LinuxDevil/agent-sdk.git
cd agent-sdk
npm install
npx lousho studio --dev   # or just `npx lousho studio` before building
```

يشغّل هذا خادم الواجهة البرمجية مباشرة من TypeScript (`tsx`) وخادم تطوير Vite حقيقيًا مع إعادة تحميل فوري للوحدات لملفات `apps/agent-forge/src/**`، كعمليتين شقيقتين. ولبناء حزمة الإنتاج التي يستخدمها الجميع سواك (وللتحقق مما يُشحن فعلًا):

```bash theme={null}
npm run build:studio   # builds apps/agent-forge/dist (client) and
                        # apps/agent-forge/dist-server (bundled server)
npx lousho studio       # now runs in production mode
```

يعمل `npm run build:studio` تلقائيًا أيضًا ضمن سكربت `prepublishOnly` في جذر المستودع، فلا يمكن لعملية `npm publish` أن تنشر استوديو قديمًا أو غير مبني.

## اختبار دخاني شامل (E2E)

`apps/agent-forge/e2e/studio.spec.ts` اختبار Playwright بلا واجهة (headless) يقود `lousho studio` الحقيقي المبني (خادم الإنتاج `dist-server/index.cjs` نفسه، لا خادم Vite في وضع التطوير) عبر متصفح: ينشئ وكيلًا من القالب "Support bot"، ويعيد توجيه عقدة الأداة فيه إلى أداة `demo-approval` محلية في الخادم (قيمتها دائمًا `needsApproval: true`؛ انظر تعليق التوثيق في `server/buildAgent.ts` لمعرفة سبب وجودها، إذ لا تشترط أي من أدوات الـ SDK المدمجة التي يمكن تحديدها من ملف المواصفات موافقةً)، ويرسل إليه رسالة محادثة تثير منطق استدعاء الأدوات التقريبي في المزوّد الوهمي، وينتظر توقف التشغيل عند بوابة الموافقة، ويوافق عليه من بطاقة الموافقة المضمّنة في تبويب Chat، ثم يتحقق من اكتمال التشغيل. شغّله بالأمر:

```bash theme={null}
npm run test:e2e:studio   # from the repo root, or apps/agent-forge/
```

يبني هذا Agent Forge أولًا (`build:studio`)، ثم يشغّل Playwright عليها.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.