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 نفسها، فلا توجد حزمة منفصلة تثبّتها:
lousho studio (أدناه) نسخة مبنية مسبقًا من التطبيق؛ ولا تحتاج إلى الشيفرة المصدرية لـ apps/agent-forge ولا إلى اعتمادياتها التطويرية (Vite وtsx وغيرهما) كي تستخدمها.
أما إذا كنت تعمل داخل المستودع الأحادي (monorepo) لهذه الـ SDK نفسها (أي تساهم في Agent Forge ذاتها)، فانظر وضع التطوير أدناه.
البدء السريع
http://127.0.0.1:4750). افتحه في المتصفح، فترى لوحة الرسم، والشريط الأيسر (وكلاؤك المحفوظون مع لوحة العُقد والخطّافات)، وInspector (على اليمين)، ودرجًا سفليًا فيه التبويبات Chat/Logs/Trace/Output/Settings.
خيارات مفيدة:
.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.
جولة بناء أول وكيل
- أنشئ وكيلًا. في تبويب “Agents” في الشريط الأيسر، انقر New، وأعطِ الوكيل اسمًا، واختر قالب بداية. القالب Blank graph (عقدة LLM واحدة تستخدم المزوّد المدمج
mock) هو أسرع طريقة للتجربة دون أي مفاتيح API. تنشئ Agent Forge الوكيل وتفتحه على لوحة الرسم. - انظر إلى الرسم البياني. الوكيل الفارغ عقدة
llmواحدة. اسحب عُقدًا أخرى من لوحة العناصر في الشريط الأيسر (Trigger وLLM step وTool call وApproval gate وResponse / output) واربط بينها بالسحب بين مقابضها. انقر عقدة لتعديل إعداداتها (الموجّه، المزوّد/النموذج، الأدوات، نقاط التوقف) في Inspector على اليمين. - شغّله. انقر Run في الشريط العلوي. مع المزوّد
mockلا شيء يحتاج إلى إعداد: فهو يعيد مخرجات جاهزة حتمية، وهذا هو المقصود تمامًا لتجربة بقية الواجهة دون الحاجة إلى مفتاح API لنموذج LLM حقيقي. يتابع مؤشر الحالة في الشريط العلوي التشغيلَ (running→idle/error/awaiting approval). - راقبه في وحدة التصحيح. افتح تبويب Logs في الدرج السفلي لترى سجلًا حيًّا قابلًا للتصفية لأحداث التشغيل (أحداث trigger/llm/tool/sandbox/checkpoint/approval)، أو تبويب Trace لترى مخططًا شلاليًا لمقاطع التتبّع (spans). فعّل Debug في الشريط العلوي (أو ضع نقطة توقف على عقدة في Inspector) لإيقاف التشغيل مؤقتًا عند حدود استدعاءات LLM والأدوات والتقدّم فيه خطوة خطوة بزرَّي Step/Continue في شريط التصحيح؛ ووسّع “Live message array” هناك لتفحص قائمة الرسائل الجارية. يعرض تبويب Output كائن
ExecutionResultكاملًا (الرسائل، استدعاءات الأدوات، الاستهلاك، الخطوات) على هيئة شجرة JSON قابلة للطي عند انتهاء التشغيل أو توقفه مؤقتًا. - حاوره. تبويب Chat قناة محادثة مستقلة (
POST /agents/:id/message، ويُبَث الرد عبر اتصال WebSocket نفسه المستخدم لكل شيء آخر): أرسل إليه رسالة فيرد في المحادثة، بمعزل عن زر “Run” الخاص بالرسم البياني أعلاه. يحتفظ كل وكيل بسجل محادثاته الخاص (يبدأ+ New chatجلسة جديدة؛ وتبقى الجلسات القديمة قابلة للتصفح). - وافق على استدعاء أداة متوقف. أضف عقدة Tool call، وافتحها في Inspector، واختر أداة. بعض الأدوات (أو سياسة الوكيل نفسه) قد تشترط موافقة بشرية قبل التنفيذ. حين يصل تشغيل أو محادثة إلى أداة كهذه، تظهر بطاقة موافقة مضمّنة (في الشريط العلوي لتشغيل الرسم البياني، أو كفقاعة رسالة في محادثة Chat) تعرض اسم الأداة ووسائطها. انقر Approve للسماح بالمتابعة أو Reject لإلغاء ذلك الاستدعاء؛ ويُستأنف التشغيل تلقائيًا في الحالتين.
الخطّافات
الخطّافات (hooks) (LOU-Q) دوال صغيرة تعمل في بيئة معزولة، وتُنفَّذ مباشرة قبل استدعاء أداة أو استدعاءgenerate لنموذج LLM أو بعده. هي الآلية نفسها التي يوفّرها قلب الـ SDK باسم HookRegistry/AgentHook (انظر نظرة عامة على الواجهة البرمجية)، لكنها هنا تُكتب مرئيًا وتُرفق بعقدة محددة على لوحة الرسم.
لإرفاق خطّاف:
- اختر عقدة
llmأوtoolعلى لوحة الرسم (لا تنطبق الخطّافات إلا على هاتين، فهما النقطتان اللتان يستدعي عندهماAgentExecutorالخارج فعلًا). - افتح قسم Hooks في Inspector. اسحب عنصر Pre-hook أو Post-hook من لوحة العناصر في الشريط الأيسر إلى العقدة (أو أفلته مباشرة في قسم Hooks) لإرفاق خطّاف جديد؛ وستُعرض عليك قوالب بداية (
redact-piiوrate-limitوaudit-logوinject-context) تتخذها نقطة انطلاق قابلة للتعديل. - انقر شارة الخطّاف لاختياره، ثم عدّل شيفرته في محرر 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. - رمي استثناء يلغي الخطوة: خطّاف تحديد المعدّل مثلًا يرمي استثناءً ليمنع استدعاء الأداة تمامًا بدل أن يتركه يُنفَّذ.
- في خطّاف استدعاء الأداة، يكون
- بدّل المفتاح على شارة الخطّاف لتفعيله أو تعطيله دون إزالته، أو استخدم زر x لإزالته كليًا. الخطّافات المفعّلة وحدها تُصرَّف ضمن التشغيل.
redact-pii):
spec.policy.hooks ضمن ملف YAML الخاص بالوكيل؛ ويصرّف الخادم الخطّافات المفعّلة إلى HookRegistry حقيقي للتشغيل (server/compileHooks.ts)، وتمر عبر SandboxAdapter نفسه الذي تستخدمه الأداة المعزولة.
السفر عبر الزمن
تحتفظ Agent Forge بنقاط الحفظ (checkpoints) كلها لكل تشغيل، لا بالأخيرة فقط: فمخزنها الملفي (server/checkpointStore.ts) يحتفظ بالسجل المحدود نفسه الذي يحتفظ به LocalStorageCheckpointStore في الـ SDK (أحدث 50 عملية حفظ لكل تشغيل، تحت .lousho/agents/<id>/checkpoint-history/؛ انظر سجل نقاط الحفظ). ومن هذا السجل تستطيع تفريع تشغيل عند أي خطوة، وتغيير ما جرى فيها، وإعادة تشغيله بجوار الأصل، ويتولى العمل AgentExecutor.fork() وcompareTrajectories().
تبويب History
- شغّل الوكيل (زر Run في الشريط العلوي، أو رسالة في Chat).
- افتح تبويب History في الدرج السفلي. يسرد خطوات التشغيل: رقم الخطوة، والحالة، وسبب انتهاء النموذج، واستدعاءات الأدوات التي جرت، وعدد الرموز (tokens) وتكلفة استدعاء النموذج في الخطوة عند توفّرهما.
- انقر Edit and replay from here على إحدى الخطوات. اختر Append a user message واكتب رسالة، أو اختر أحد استدعاءات الأدوات في الخطوة لتعديل نتيجته (يُملأ الحقل مسبقًا بالنتيجة المسجَّلة؛ والنص الذي يصح تحليله كـ JSON يُرسَل كـ JSON).
- انقر Fork and replay. يُفرَّع التشغيل عند تلك الخطوة مع تعديلك ويبدأ كتشغيل جديد باسم
<id>.fork-<n>. - يُفتح الفرع بجوار الأصل في عرض لمسارَي التنفيذ جنبًا إلى جنب: كل دورة نموذج في التشغيلين (النص، واستدعاءات الأدوات ونتائجها)، مع إبراز أول دورة يختلفان فيها بوسم diverged، وتحتها عناصر الانحراف (ترتيب الأدوات، الوسائط، عدد الخطوات، سبب الانتهاء). ويُحدَّث العرض عند انتهاء الفرع.
المسارات
معرّف التشغيل هو معرّف جلسة نقاط الحفظ الخاصة به: معرّف الوكيل لتشغيلات الوكيل نفسه، و<id>.fork-<n> لفرع من التشغيل <id>. لدى خادم التحكم في وقت التشغيل ثلاثة مسارات له (يستخدمها تبويب History):
تسلسل العمل، لوكيل اسمه
weather شُغِّل مرة واحدة:
الإعدادات والأسرار وربط النشر
في الدرج السفلي تبويب Settings من ثلاثة أجزاء: مفاتيح API للمزوّدين (OpenAI وAnthropic، تُخزَّن مشفّرة تحت.lousho/ ولا تُعرض مرة أخرى أبدًا)، وملفات إعدادات مسمّاة (المزوّد، مهايئ النشر، مهلة الخطّاف، مفتاح تفعيل OpenTelemetry؛ وتُحفظ في .lousho/settings.json الذي لا يحوي أسرارًا)، وقسم Deploy يختار مهايئًا (node-server أو docker أو cloudflare-worker) ويشغّل lousho build للوكيل المحدد. أما بقية المزوّدين فما زالوا يقرؤون متغيرات البيئة الخاصة بهم، كما يفعل lousho dev وlousho build (انظر الإعداد)، والمزوّد mock لا يحتاج إلى بيانات اعتماد.
وضع التطوير
إذا كنت تعمل داخل المستودع الأحادي لهذه الـ SDK نفسها (تساهم في Agent Forge ذاتها، لا تستخدمها فحسب)، فإنlousho studio ينتقل إلى وضع التطوير تلقائيًا ما دام apps/agent-forge/dist-server لم يُبنَ بعد:
tsx) وخادم تطوير Vite حقيقيًا مع إعادة تحميل فوري للوحدات لملفات apps/agent-forge/src/**، كعمليتين شقيقتين. ولبناء حزمة الإنتاج التي يستخدمها الجميع سواك (وللتحقق مما يُشحن فعلًا):
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، ثم يتحقق من اكتمال التشغيل. شغّله بالأمر:
build:studio)، ثم يشغّل Playwright عليها.