"""Curated, local agent skills with explicit tool permissions.""" from dataclasses import dataclass @dataclass(frozen=True) class AgentSkill: id: str name: str description: str instructions: str allowed_tools: frozenset[str] def public_metadata(self) -> dict[str, object]: return { "id": self.id, "name": self.name, "description": self.description, "allowed_tools": sorted(self.allowed_tools), } SKILLS: dict[str, AgentSkill] = { "code_explain": AgentSkill( id="code_explain", name="شرح الكود", description="يفسر الغرض وتدفق البيانات والدوال المهمة، مع الاستشهاد بالمسار والسطر عند توفرهما.", instructions=( "اشرح الملفات المحددة على مراحل: الغرض العام، تدفق البيانات، ثم أهم الدوال. " "استشهد بمسار الملف ورقم السطر عندما يظهر في المقتطف، وميّز بين ما قرأته وما استنتجته. " "استعمل البحث المعرفي للوثائق المفهرسة عند الحاجة. لا تقترح تعديلًا ولا تطلب أداة كتابة في هذه المهارة." ), allowed_tools=frozenset({"calculator", "search_workspace", "search_knowledge"}), ), "code_review": AgentSkill( id="code_review", name="مراجعة الكود", description="يركز على العيوب القابلة للتحقق والأمان والأخطاء الحدية، ويصنفها حسب الخطورة.", instructions=( "راجع الكود بحثًا عن عيوب قابلة لإعادة الإنتاج في الصحة والأمان ومعالجة الأخطاء والحدود. " "اعرض النتائج أولًا مرتبة حسب الخطورة، مع المسار والسطر والدليل والأثر. " "لا تختلق مشاكل أسلوبية. لا تطلب propose_file_change إلا إذا طلب المستخدم صراحةً إصلاحًا أو تعديلًا؛ " "وحتى عندئذٍ لا تطبق الكتابة، بل حضّر معاينة diff فقط." ), allowed_tools=frozenset({"calculator", "search_workspace", "search_knowledge", "propose_file_change"}), ), "test_plan": AgentSkill( id="test_plan", name="خطة اختبارات", description="يستخرج حالات النجاح والحواف والفشل من الكود ويكتب خطوات ونتائج متوقعة دون تشغيلها.", instructions=( "أنشئ خطة اختبارات قابلة للتنفيذ يدويًا: المسار الطبيعي، المدخلات الحدية، وحالات الفشل. " "لكل حالة اذكر الإعداد والمدخل والنتيجة المتوقعة. لا تدّع أنك شغّلت اختبارًا ولا تشغّل أوامر. " "اربط الحالات بالدوال أو الملفات التي قرأتها فقط." ), allowed_tools=frozenset({"search_workspace", "search_knowledge"}), ), } def get_skill(skill_id: str | None) -> AgentSkill | None: return SKILLS.get(skill_id) if skill_id is not None else None