تخطَّ إلى المحتوى

اكتشاف واختيار وكيل المهام

يصف هذا المستند كيف يكتشف النظام الفرعي للمهام تعريفات الوكلاء، ويدمج المصادر المتعددة، ويحل الوكيل المطلوب في وقت التنفيذ.

يغطي هذا المستند سلوك وقت التشغيل كما هو مُنفَّذ حالياً، بما في ذلك الأسبقية، ومعالجة التعريفات غير الصالحة، وقيود الإنشاء/العمق التي يمكن أن تجعل الوكيل غير متاح فعلياً.


يتم تطبيع وكلاء المهام إلى AgentDefinition (src/task/types.ts):

  • name، description، systemPrompt (مطلوبة لوكيل محمَّل صالح)
  • اختيارية: tools، spawns، model، thinkingLevel، output
  • source: "bundled" | "user" | "project"
  • filePath اختياري

يأتي التحليل من frontmatter عبر parseAgentFields() (src/discovery/helpers.ts):

  • name أو description مفقود => غير صالح (null)، المُستدعي يعامله كفشل في التحليل
  • tools يقبل CSV أو مصفوفة؛ إذا تم توفيره، يُضاف submit_result تلقائياً
  • spawns يقبل *، CSV، أو مصفوفة
  • سلوك التوافق العكسي: إذا كان spawns مفقوداً لكن tools يتضمن task، يصبح spawns هو *
  • output يُمرَّر كبيانات مخطط غير شفافة

الوكلاء المُضمَّنون يتم تضمينهم في وقت البناء (src/task/agents.ts) باستخدام استيراد النصوص.

EMBEDDED_AGENT_DEFS يُعرِّف:

  • explore، plan، designer، reviewer من ملفات الموجِّهات
  • task و quick_task من نص task.md المشترك بالإضافة إلى frontmatter المحقون

مسار التحميل:

  1. loadBundledAgents() يحلل الـ markdown المُضمَّن باستخدام parseAgent(..., "bundled", "fatal")
  2. النتائج تُخزَّن مؤقتاً في الذاكرة (bundledAgentsCache)
  3. clearBundledAgentsCache() هي إعادة تعيين ذاكرة التخزين المؤقت للاختبار فقط

لأن التحليل المُضمَّن يستخدم level: "fatal"، فإن frontmatter المُضمَّن المشوَّه يرمي استثناءً ويمكن أن يُفشل الاكتشاف بالكامل.

اكتشاف نظام الملفات والإضافات

Section titled “اكتشاف نظام الملفات والإضافات”

discoverAgents(cwd, home) (src/task/discovery.ts) يدمج الوكلاء من أماكن متعددة قبل إلحاق التعريفات المُضمَّنة.

  1. مجلدات وكلاء تكوين المستخدم من getConfigDirs("agents", { project: false })
  2. أقرب مجلدات وكلاء المشروع من findAllNearestProjectConfigDirs("agents", cwd)
  3. جذور إضافات Claude (listClaudePluginRoots(home)) مع مجلدات agents/ الفرعية
  4. الوكلاء المُضمَّنون (loadBundledAgents())

ترتيب عائلة المصدر يأتي من getConfigDirs("", { project: false })، المُشتق من priorityList في src/config.ts:

  1. .xcsh
  2. .claude
  3. .codex
  4. .gemini

لكل عائلة مصدر، ترتيب الاكتشاف هو:

  1. أقرب مجلد مشروع لذلك المصدر (إن وُجد)
  2. مجلد المستخدم لذلك المصدر

بعد جميع مجلدات عائلات المصادر، تُلحق مجلدات agents/ الخاصة بالإضافات (إضافات نطاق المشروع أولاً، ثم نطاق المستخدم).

الوكلاء المُضمَّنون يُلحقون أخيراً.

تحذير مهم: التعليقات القديمة مقابل الكود الحالي

Section titled “تحذير مهم: التعليقات القديمة مقابل الكود الحالي”

تعليقات رأس discovery.ts لا تزال تذكر .pi ولا تذكر .codex/.gemini. الترتيب الفعلي في وقت التشغيل مدفوع بـ src/config.ts ويستخدم حالياً .xcsh، .claude، .codex، .gemini.

يستخدم الاكتشاف إلغاء التكرار بأسلوب الأول يفوز بمطابقة دقيقة لـ agent.name:

  • Set<string> يتتبع الأسماء المرئية.
  • الوكلاء المحمَّلون يُسطَّحون بترتيب المجلد ويُحتفظ بهم فقط إذا كان الاسم غير مرئي.
  • الوكلاء المُضمَّنون يُفلترون مقابل نفس المجموعة ويُضافون فقط إذا كانوا لا يزالون غير مرئيين.

الآثار المترتبة:

  • المشروع يتجاوز المستخدم لنفس عائلة المصدر.
  • عائلة المصدر ذات الأولوية الأعلى تتجاوز الأدنى (.xcsh قبل .claude، إلخ).
  • الوكلاء غير المُضمَّنين يتجاوزون الوكلاء المُضمَّنين بنفس الاسم.
  • مطابقة الأسماء حساسة لحالة الأحرف (Task و task مختلفان).
  • ضمن مجلد واحد، تُقرأ ملفات markdown بترتيب أسماء الملفات المعجمي قبل إلغاء التكرار.

سلوك ملف الوكيل غير الصالح/المفقود

Section titled “سلوك ملف الوكيل غير الصالح/المفقود”

لكل مجلد (loadAgentsFromDir):

  • مجلد غير قابل للقراءة/مفقود: يُعامل كفارغ (readdir(...).catch(() => []))
  • فشل قراءة أو تحليل الملف: يُسجَّل تحذير، يُتخطى الملف
  • مسار التحليل يستخدم parseAgent(..., level: "warn")

سلوك فشل Frontmatter يأتي من parseFrontmatter:

  • خطأ التحليل عند مستوى warn يُسجِّل تحذيراً
  • المحلل يعود إلى محلل بسيط لسطور key: value
  • إذا كانت الحقول المطلوبة لا تزال مفقودة، يفشل parseAgentFields، ثم يُرمى AgentParsingError ويُلتقط من قبل المُستدعي (يُتخطى الملف)

التأثير الصافي: ملف وكيل مخصص سيئ واحد لا يوقف اكتشاف الملفات الأخرى.

البحث هو بحث خطي بالاسم الدقيق:

  • getAgent(agents, name) => agents.find(a => a.name === name)

في تنفيذ المهمة (TaskTool.execute):

  1. يُعاد اكتشاف الوكلاء في وقت الاستدعاء (discoverAgents(this.session.cwd))
  2. params.agent المطلوب يُحل عبر getAgent
  3. الوكيل المفقود يعيد استجابة أداة فورية:
    • Unknown agent "...". Available: ...
    • لا تعمل أي عملية فرعية

الوصف مقابل اكتشاف وقت التنفيذ

Section titled “الوصف مقابل اكتشاف وقت التنفيذ”

TaskTool.create() يبني وصف الأداة من نتائج الاكتشاف في وقت التهيئة (buildDescription).

execute() يُعيد اكتشاف الوكلاء مرة أخرى. لذا يمكن أن تختلف مجموعة وقت التشغيل عما تم إدراجه في وصف الأداة السابق إذا تغيرت ملفات الوكلاء أثناء الجلسة.

حواجز المخرجات المُهيكلة وأسبقية المخطط

Section titled “حواجز المخرجات المُهيكلة وأسبقية المخطط”

أسبقية مخطط المخرجات في وقت التشغيل في TaskTool.execute:

  1. output في frontmatter الوكيل
  2. params.schema في استدعاء المهمة
  3. outputSchema للجلسة الأم

(effectiveOutputSchema = effectiveAgent.output ?? outputSchema ?? this.session.outputSchema)

نص حاجز الحماية في وقت الموجِّه في src/prompts/tools/task.md يحذر من سلوك عدم التطابق لوكلاء المخرجات المُهيكلة (explore، reviewer): تعليمات تنسيق المخرجات في النص يمكن أن تتعارض مع المخطط المُدمج وتنتج مخرجات null.

هذا توجيه، وليس منطق تحقق صارم في وقت التشغيل في discoverAgents.

src/task/commands.ts هو بنية تحتية موازية لأوامر سير العمل (وليست تعريفات وكلاء)، لكنها تتبع نفس النمط العام:

  • الاكتشاف من مزودي القدرات أولاً
  • إلغاء التكرار بالاسم بأسلوب الأول يفوز
  • إلحاق الأوامر المُضمَّنة إذا كانت لا تزال غير مرئية
  • البحث بالاسم الدقيق عبر getCommand

في src/task/index.ts، تُعاد تصدير مساعدات الأوامر مع مساعدات اكتشاف الوكلاء. اكتشاف الوكلاء نفسه لا يعتمد على اكتشاف الأوامر في وقت التشغيل.

قيود التوفر خارج نطاق الاكتشاف

Section titled “قيود التوفر خارج نطاق الاكتشاف”

يمكن أن يكون الوكيل قابلاً للاكتشاف ولكنه لا يزال غير متاح للتشغيل بسبب حواجز التنفيذ.

TaskTool.execute يتحقق من session.getSessionSpawns():

  • "*" => السماح بأي وكيل
  • "" => رفض الكل
  • قائمة CSV => السماح بالأسماء المدرجة فقط

إذا رُفض: استجابة فورية Cannot spawn '...'. Allowed: ....

حارس بيئي لمنع التكرار الذاتي

Section titled “حارس بيئي لمنع التكرار الذاتي”

PI_BLOCKED_AGENT يُقرأ عند إنشاء الأداة. إذا تطابق الطلب، يُرفض التنفيذ مع رسالة منع التكرار.

بوابة عمق التكرار (توفر أداة المهمة داخل الجلسات الفرعية)

Section titled “بوابة عمق التكرار (توفر أداة المهمة داخل الجلسات الفرعية)”

في runSubprocess (src/task/executor.ts):

  • العمق يُحسب من taskDepth
  • task.maxRecursionDepth يتحكم في حد القطع
  • عند الوصول للعمق الأقصى:
    • أداة task تُزال من قائمة أدوات الطفل
    • spawns الخاص ببيئة الطفل يُعيَّن كفارغ

لذا المستويات الأعمق لا يمكنها إنشاء مهام إضافية حتى لو كان تعريف الوكيل يتضمن spawns.

تحذير بشأن وضع التخطيط (التنفيذ الحالي)

Section titled “تحذير بشأن وضع التخطيط (التنفيذ الحالي)”

TaskTool.execute يحسب effectiveAgent لوضع التخطيط (يُقدِّم موجِّه وضع التخطيط، يفرض مجموعة فرعية من الأدوات للقراءة فقط، يُفرغ spawns)، لكن runSubprocess يُستدعى مع agent بدلاً من effectiveAgent.

التأثير الحالي:

  • تجاوز النموذج / مستوى التفكير / مخطط المخرجات مُشتقة من effectiveAgent
  • موجِّه النظام وقيود الأدوات/الإنشاء من effectiveAgent لا تُمرَّر في مسار الاستدعاء هذا

هذا تحذير تنفيذي يستحق المعرفة عند قراءة توقعات سلوك وضع التخطيط.