> ## Documentation Index
> Fetch the complete documentation index at: https://twenty-claude-cool-pascal-5ay683.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# المهارات والوكلاء

> عرّف مهارات ووكلاء الذكاء الاصطناعي لتطبيقك.

<Warning>
  المهارات والوكلاء حاليًا في مرحلة الألفا. الميزة تعمل لكنها لا تزال قيد التطور.
</Warning>

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

<AccordionGroup>
  <Accordion title="defineSkill" description="عرّف مهارات وكلاء الذكاء الاصطناعي">
    تُحدِّد المهارات تعليمات وإمكانات قابلة لإعادة الاستخدام يمكن لوكلاء الذكاء الاصطناعي استخدامها داخل مساحة العمل لديك. استخدم `defineSkill()` لتعريف مهارات مع تحقّق مدمج:

    ```ts src/skills/example-skill.ts theme={null}
    import { defineSkill } from 'twenty-sdk/define';

    export default defineSkill({
      universalIdentifier: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
      name: 'sales-outreach',
      label: 'Sales Outreach',
      description: 'Guides the AI agent through a structured sales outreach process',
      icon: 'IconBrain',
      content: `You are a sales outreach assistant. When reaching out to a prospect:
    1. Research the company and recent news
    2. Identify the prospect's role and likely pain points
    3. Draft a personalized message referencing specific details
    4. Keep the tone professional but conversational`,
    });
    ```

    النقاط الرئيسية:

    * `name` هي سلسلة معرّف فريدة للمهارة (يُنصَح باستخدام kebab-case).
    * `label` هو اسم العرض المقروء للبشر الظاهر في واجهة المستخدم.
    * `content` يحتوي على تعليمات المهارة — وهو النص الذي يستخدمه وكيل الذكاء الاصطناعي.
    * `icon` (اختياري) يحدّد الأيقونة المعروضة في واجهة المستخدم.
    * `description` (اختياري) يوفّر سياقًا إضافيًا حول غرض المهارة.
  </Accordion>

  <Accordion title="defineAgent" description="عرِّف وكلاء الذكاء الاصطناعي باستخدام موجهات مخصّصة">
    الوكلاء هم مساعدون ذكاء اصطناعي يعيشون داخل مساحة العمل لديك. استخدم `defineAgent()` لإنشاء وكلاء بموجه نظام مخصّص:

    ```ts src/agents/example-agent.ts theme={null}
    import { defineAgent } from 'twenty-sdk/define';

    export default defineAgent({
      universalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
      name: 'sales-assistant',
      label: 'Sales Assistant',
      description: 'Helps the sales team draft outreach emails and research prospects',
      icon: 'IconRobot',
      prompt: 'You are a helpful sales assistant. Help users with their questions and tasks.',
    });
    ```

    النقاط الرئيسية:

    * `name` هي سلسلة معرّف فريدة للوكيل (يُنصح باستخدام kebab-case).
    * `label` هو اسم العرض الظاهر في واجهة المستخدم.
    * `prompt` هو موجه النظام الذي يحدّد سلوك الوكيل.
    * `description` (اختياري) يوفّر سياقًا حول ما يفعله الوكيل.
    * `icon` (اختياري) يحدّد الأيقونة المعروضة في واجهة المستخدم.
    * `modelId` (اختياري) يتجاوز نموذج الذكاء الاصطناعي الافتراضي الذي يستخدمه الوكيل.
    * `responseFormat` (اختياري) يتحكم في شكل مخرجات الوكيل. القيمة الافتراضية هي `{ type: 'text' }` للنص الحر. استخدم `{ type: 'json', schema }` لفرض مخرجات JSON منظمة.

    بشكل افتراضي، يعيد الوكيل نصًا حرًا. للحصول على مخرجات منظمة، عيّن `responseFormat` إلى `{ type: 'json' }` ووفّر `schema`:

    ```ts src/agents/structured-agent.ts theme={null}
    import { defineAgent } from 'twenty-sdk/define';

    export default defineAgent({
      universalIdentifier: 'c4d5e6f7-a8b9-0123-cdef-456789012345',
      name: 'lead-scorer',
      label: 'Lead Scorer',
      prompt: 'Score the lead and explain your reasoning.',
      responseFormat: {
        type: 'json',
        schema: {
          type: 'object',
          properties: {
            score: { type: 'number', description: 'Lead score from 0 to 100' },
            summary: { type: 'string', description: 'Short reasoning for the score' },
          },
          required: ['score', 'summary'],
          additionalProperties: false,
        },
      },
    });
    ```

    ملاحظات حول المخطط:

    * المخطط كائن مسطح: يجب أن يكون `type` لكل خاصية نوعًا بدائيًا (`string` أو `number` أو `boolean`). الكائنات المتداخلة والمصفوفات غير مدعومة.
    * `description` (اختياري) على كل خاصية يوجه النموذج لما يجب وضعه هناك.
    * `required` (اختياري) يسرد الخصائص التي يجب على النموذج إرجاعها دائمًا.
    * `additionalProperties: false` (اختياري) يمنع أي خاصية غير معرّفة في `properties`.
  </Accordion>

  <Accordion title="runAgent" description="تشغيل وكيل من دالة منطقية">
    تتيح `runAgent()` لدالة منطقية تشغيل أحد وكلاء تطبيقك (مع مهاراته وأدواته). حدِّد الوكيل بواسطة `universalIdentifier` الذي مررته إلى `defineAgent()`. مرر إما سلسلة `prompt` أو سجل المحادثة `messages`
    — وليس كليهما معًا:

    ```ts src/logic-functions/run-enricher.ts theme={null}
    import { runAgent } from 'twenty-sdk/logic-function';

    const { result, error, success } = await runAgent({
      agentUniversalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
      prompt: 'Enrich House Ad <recordId>: fill empty fields from its listing URL.',
    });
    ```

    لبوتات المحادثة متعددة الجولات (Slack, Discord, Teams, …)، مرر سجل سلسلة المحادثة كـ
    `messages` بدلًا من استخدام `prompt` واحد فقط:

    ```ts src/logic-functions/reply-in-thread.ts theme={null}
    import { runAgent } from 'twenty-sdk/logic-function';

    const { result, error, success } = await runAgent({
      agentUniversalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
      messages: [
        { role: 'user', content: 'Who owns Acme?' },
        { role: 'assistant', content: 'Sarah owns the Acme account.' },
        { role: 'user', content: 'What was the last touchpoint?' },
      ],
    });
    ```

    النقاط الرئيسية:

    * قدِّم **واحدًا فقط** من `prompt` (سلسلة نصية) أو `messages` (من 1 إلى 100 عنصر من `{ role: 'user' | 'assistant', content: string }`).
    * يعمل الوكيل **بشكل متزامن** ويمكنه قراءة/تحديث السجلات بنفسه عبر أدواته الخاصة — يتم حل `runAgent()` بمجرد اكتمال التشغيل.
    * لا يمكن للتطبيق تشغيل سوى وكلائه الخاصين.
    * يجب أن يمنح [الدور الافتراضي](/l/ar/developers/extend/apps/config/roles) للتطبيق علامة الإذن `AI` — أضِف `SystemPermissionFlag.AI` إلى `permissionFlagUniversalIdentifiers` الخاصة به (أو عيِّن `canAccessAllTools: true`).
      بدون ذلك، تفشل `runAgent()` بخطأ في الأذونات.
    * اضبط قيمة كبيرة لـ `timeoutSeconds` على الدالة المنطقية — قد يستغرق تشغيل الوكيل عدة ثوانٍ.
    * يكون `success` بقيمة `true` و`result` غير فارغ عند اكتمال التشغيل؛ في حال الفشل يكون `success` بقيمة `false`، و`result` بقيمة `null`، وتحتوي `error` على السبب (على سبيل المثال، عندما تنفد أرصدة الذكاء الاصطناعي الخاصة بمساحة العمل أثناء التشغيل).

    ```ts src/roles/default-role.ts theme={null}
    import { defineApplicationRole, SystemPermissionFlag } from 'twenty-sdk/define';

    export default defineApplicationRole({
      universalIdentifier: 'b648f87b-1d26-4961-b974-0908fd991061',
      label: 'Default function role',
      // runAgent() requires the AI permission flag on the app's default role.
      permissionFlagUniversalIdentifiers: [SystemPermissionFlag.AI],
    });
    ```

    <Warning>
      **تجنب الحلقات:** إذا استدعيت `runAgent()` من مشغل حدث قاعدة بيانات من نوع `*.updated` وقام الوكيل بتحديث نفس السجل، فحدد نطاق المشغل باستخدام `updatedFields` إلى حقل لا يكتبه الوكيل أبدًا (مثل عنوان URL المصدر)، أو تحقَّق مما إذا كان أي حقل مستهدف لا يزال فارغًا قبل استدعاء `runAgent()`.
    </Warning>

    ### التشغيل نيابةً عن أحد أعضاء مساحة العمل

    مرر `runAsWorkspaceMemberId` عندما يتم تشغيل التنفيذ بواسطة شخص — مثل روبوت دردشة يجيب على رسالة، مثلاً — لكي يتصرف الوكيل بصفة ذلك العضو بدلًا من التطبيق:

    ```ts src/logic-functions/answer-question.ts theme={null}
    const { result } = await runAgent({
      agentUniversalIdentifier: 'b3c4d5e6-f7a8-9012-bcde-f34567890123',
      prompt: 'How many open opportunities do we have?',
      runAsWorkspaceMemberId: '20202020-0687-4c41-b707-ed1bfca972a7',
    });
    ```

    ثم يعمل التنفيذ باستخدام **دور العضو نفسه**: يمكنه القيام بكل ما يمكن
    لذلك العضو القيام به ولا أكثر، وتنسب إليه السجلات التي ينشئها، وتُطبَّق أذوناتُه على مستوى الصف. لا يشارك دور الوكيل — فهو الإعداد الافتراضي للتطبيق لعمليات التنفيذ التي لا يقف خلفها أي شخص. احذف الحقل في عمليات التنفيذ الذاتية (المهام المجدولة، مشغلات أحداث قاعدة البيانات): في هذه الحالة يحتفظ الوكيل بدوره الخاص. يبقى التطبيق الفاعل مرتبطًا بسياق التنفيذ لأغراض التتبّع وإثبات المصدر، دون تقييد أذونات العضو.

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

    * يمكن لرمز **بدون مستخدم مرفق** أن يسمّي أي عضو. تعمل الدالة المنطقية بدون مستخدم، وكذلك الرموز المُنشأة عبر `client_credentials` أو من مفتاح API.
    * لا يمكن لرمز مُصدَر **نيابةً عن مستخدم**، كما يستقبله مكوّن الواجهة الأمامية، أن يسمّي إلا العضو الخاص بذلك المستخدم فقط.

    لا يمكن لأي شيء آخر — جلسة مستخدم عادية، أو مفتاح API بدون رمز تطبيق — أن يسمّي عضوًا على الإطلاق.

    <Warning>
      يقوم `runAgent()` بإطلاق استثناء عندما يتعذّر حل عضو مساحة العمل — مثل عضو غير معروف أو تمت إزالته، أو ليس لديه أي دور. لا يعود إطلاقًا إلى دور الوكيل نفسه، لأن ذلك سيمنح صلاحيات وصول أكثر مما طلبه المستدعي.
    </Warning>
  </Accordion>
</AccordionGroup>
