بنية بروتوكول عميل الوكيل

تقوم ACP بتوحيد العلاقة بين واجهة برمجة ووكيل برمجة. وهي تمنحهما طريقة مشتركة لتأسيس القدرات، وفتح جلسة مشروع، وتبادل المطالبات، وبثّ التقدم، وطلب الإذن، وإلغاء العمل، وإغلاق الجلسة أو استئنافها.

الدوران

الدورالمسؤوليات
العميل / المضيفيبدأ عملية الوكيل، ويعرض الواجهة البشرية، ويحدد مساحة العمل، ويزوّد بالملفات الطرفية الاختيارية وMCP والخوادم، ويطبق سياسة الأذونات، ويعرض التحديثات الحية
وكيل ACPيقبل جلسات المشروع والمطالبات، وينفذ أعمال البرمجة، ويبلغ عن الرسائل ونشاط الأدوات، ويطلب الإذن عند الحاجة، ويعيد سبب إيقاف مُنَمط

يمكن أن يشغل ADK-Rust أيًّا من الدورين. هذان اتجاهان للنشر، وليس بروتوكولين مختلفين.

Rendering architecture…

عندما يستهلك ADK-Rust وكيلَ ترميزٍ آخر، يكون الجانب الأيسر هو ADK-Rust والجانب الأيمن هو العملية الخارجية. وعندما يستهلك محرر وكيلًا من ADK-Rust، يمتلك المحرر الجانب الأيسر وAcpServer يمتلك الجانب الأيمن.

جولة واحدة من ACP

Rendering architecture…

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

هوية الجلسة والحالة

تعرّف جلسة ACP محادثةً مستمرة حول مشروع واحد. وهي تحتوي على cwd مطلق، ومجلدات إضافية اختيارية، وعدة طلبات، وتحديثات متدفقة، ودورة حياة. في خادم ADK-Rust، تُربط جلسة ACP واحدة بجلسة ADK-Rust واحدة، بحيث تظل محفوظات النموذج وحالة الجلسة مرتبطتين بالمحادثة نفسها.

إغلاق اتصال نشط يختلف عن حذف السجلّات المحفوظة:

  • session/close يحرّر الجلسة النشطة وعملياتها؛
  • session/resume يَصل بحالة جلسة ADK المحفوظة؛
  • session/load يعيد تنشيط جلسة محفوظة ويعيد تشغيل محادثتها المخزنة إلى العميل كإشعارات session/update مرتبة قبل اكتمال الطلب؛
  • session/fork يتفرع من جلسة محفوظة إلى معرف جلسة جديد تكون محفوظاتها المخزنة نسخة من محفوظات المصدر، مع ترك المصدر دون تغيير؛
  • session/delete يزيل الجلسة المحفوظة؛
  • session/list يعيد الجلسات المرئية عبر SessionService المكوَّن.

session/load يتحقق من cwd المقدم مقابل دليل العمل المخزن للجلسة بالطريقة نفسها التي يفعلها session/resume، ويعيد خطأ عدم العثور على الجلسة لمعرّف جلسة غير معروف. تربط إعادة التشغيل كل حدث مستخدم أو وكيل أو فكرة أو أداة مخزن بنظيره من variants SessionUpdate بالترتيب الزمني الأصلي، بحيث يعيد المحرر الذي يعاود الاتصال استعادة السجل المرئي بالترتيب الذي حدث به.

عناصر التحكم التفاعلية للجلسة

قد يوفّر الوكيل عناصر تحكم تفاعلية للعميل من خلال توفير موفّر SessionControls. وعندما يفعل ذلك، يعلنها الخادم في الردود session/new وsession/load وsession/resume وsession/fork:

  • الأوضاع — مجموعة من الأوضاع المسماة (على سبيل المثال "ask" مقابل "code") مع اختيار حالي. يتحقق session/set_mode من الوضع المطلوب مقابل المجموعة المُعلنة، ويسجله، ويصدر CurrentModeUpdate؛ ويُرفض الوضع غير المعروف ويظل الوضع الحالي دون تغيير.
  • خيارات التكوين — محددات ومفاتيح تبديل يمكن للعميل قراءتها وتغييرها. يتحقق session/set_config_option من القيمة مقابل الخيارات المعلنة للاختيار، ويسجلها، ويصدر ConfigOptionUpdate؛ ويُرفض الخيار غير المعروف أو القيمة غير الصالحة.
  • الأوامر المتاحة — أوامر الشرطة المائلة ACP المعروضة كـ AvailableCommandsUpdate عندما تصبح الجلسة نشطة.

تستمر اختيارات الوضع والتكوين في حالة جلسة ADK (acp:mode، acp:config:<id>)، لذلك فهي تبقى عبر التحميل والاستئناف والتفرّع. يظهر عنوان الجلسة المسجّل كـ SessionInfoUpdate عند التفعيل وكلما تغيّر. يوجد تعيين تحديث Plan، لكنه يظل خاملاً حتى تُظهر primitive خطة ADK إدخالات الخطة. أما الوكيل الذي لا يوفّر SessionControls فلا يعلن أوضاعًا ولا خيارات، مما يبقي القدرات المُعلنة متطابقة تمامًا مع ما ينفذه الخادم.

المحتوى يعبر الحدود عبر تعيين واحد

الطلبات الواردة من العميل والتحديثات المتدفقة إليه تمرّان عبر وحدة محتوى واحدة تعين قيم ACP ContentBlock إلى قيم adk_core::Part وبالعكس. إن الإبقاء على تعيين واحد في الاتجاهين يعني أن محلل الطلب في الخادم، ومُرسِل التدفق في الخادم، والعميل جميعهم يتفقون على كيفية تمثيل كل نوع محتوى.

يحافظ التعيين على الحمولات بدقة. تُعيَّن كتل النص إلى Part::Text مع بقاء السلسلة كما هي. تُعيَّن كتل الموردات المضمّنة إلى Part::EmbeddedResource، مع الاحتفاظ بـ URI المصدر، ونوع MIME الاختياري، والمحتويات. ينتقل المورد النصي حرفيًا في كلا الاتجاهين ولا يُشفَّر مطلقًا بـ base64؛ أما المورد الثنائي فيُشفَّر بـ base64 أثناء النقل ويُفك إلى بايتات خام على جانب ADK من الحدود. تُعيَّن كتل الصورة والصوت إلى Part::InlineData، مع الحفاظ على نوع MIME والبايتات المفكوكة؛ ويعلن الخادم ويقبل وسائط الطلب تلك، وينقل العميل المحتوى غير النصي ADK (المورد المضمَّن، الصورة، الصوت) ككتلة ACP المطابقة بدلًا من إسقاطه.

التحديثات المتدفقة تحمل أكثر من النص

أثناء تشغيل الطلب، يترجم الخادم أحداث ADK المكتوبة إلى إشعارات ACP session/update. يصبح نص النموذج وأفكاره أجزاءً من الرسالة والفكرة، ويصبح محتوى المورد المضمَّن جزءًا من رسالة مورد مضمَّن. وإلى جانب هذا السطح، يمنح نوعان من التحديث العميل رؤية أغنى للجولة:

  • تحديثات الاستخدام. عندما يحمل حدث ADK بيانات وصفية للاستخدام، يرسل الخادم UsageUpdate يعكس عدّ التوكنات المُبلّغ عنه، إضافةً إلى التكلفة بالدولار الأمريكي عندما يبلغها وقت التشغيل. الأحداث من دون بيانات وصفية للاستخدام لا تنتج أي تحديث، والخادم لا يختلق الأعداد أبدًا.
  • تحديثات استدعاء الأدوات الغنية. يبدأ استدعاء الأداة كـ ToolCall مع kind أداة مستنتج من السلوك المعلن للأداة. وتحمل ToolCallUpdate اللاحقة محتوى نتيجة الأداة ومواقع الملفات التي تفيد الأداة بأنها تأثرت بها، بحيث يستطيع المحرر عرض الفروق وقوائم الملفات المتأثرة. ويحافظ التحديث على المعرّف نفسه الخاص بـ ToolCall المنشأ، مما يصون الترابط عبر الجولة.

تتمتع جهة العميل بنفس درجة المطابقة. عندما يستهلك تطبيق ADK-Rust External_Agent، فإن سطح البث لديه (OutputChunk) لا يعرِض نصوص الوكيل وأفكاره فحسب، بل يعرِض أيضًا External_Agent ToolCallUpdate (بوصفه تحديث أداة مرتبطًا بالمعرّف ويحمل الحالة، والنوع، والعنوان، ونص المحتوى، ومواقع الملفات المتأثرة) وUsageUpdate (الأرقام المستخدمة والحجم، بالإضافة إلى التكلفة والعملة عند الإبلاغ عنهما). يُعرَض نص رسالة الوكيل كما كان من قبل تمامًا، لذا لا تتأثر مستهلكات النص الحالية.

طلبات الأذونات تربط تأكيدات الأدوات

يمكن لوكيل ADK-Rust أن يوقف تمريرًا بانتظار موافقة بشرية على استدعاء أداة (ToolConfirmationRequest). على جانب الخادم، تتحول هذه الإيقافية إلى طلب أصلي من ACP session/request_permission يصف الأداة ووسائطها. تستأنف نتيجة العميل التمرير: الموافقة تُطابق الإذن، والرفض أو الإلغاء كلاهما يُطابق الرفض، لذا فإن الطلب الملغى لا ينفذ الأداة أبدًا. تُربط كل نتيجة بالاستدعاء الدقيق عبر معرّف استدعاء الدالة الخاص به، ثم تُعاد إلى المشغّل عبر قرارات تأكيد الأداة. يُرسَل طلب الإذن المتداخل من مهمة المطالبة المُنشأة، لذلك تكتمل استجابة session/prompt الخارجية بشكل طبيعي.

القدرات هي عقد

التهيئة ليست مصافحة شكلية. يعلن كل طرف فقط عن العمليات والمحتوى الذي يدعمه. يستخدم ADK-Rust هذه القدرات لتجنب إرسال إعدادات اختيارية HTTP أو SSE MCP إلى وكيل لا يقبل إلا stdio، كما يعلن عن عمليات نظام الملفات أو المضيف الطرفي فقط عندما يوفّر التطبيق التنفيذ المقابل.

يعلن الخادم بدقة عن أنواع المحتوى التي يقبلها معالج المطالبة الخاص به. يعلن عن قدرات المطالبة embedded_context وimage وaudio لأن محتوى المورد المضمّن يُطابِق adk_core::Part::EmbeddedResource، كما أن محتوى الصورة والصوت يُطابِق adk_core::Part::InlineData. ويعلن عن load_session لأنه يسجل معالج session/load، وعن قدرة الجلسة fork لأنه يسجل معالج session/fork. تُعلن أوضاع الجلسة وخيارات الإعداد فقط عندما يوفّر الوكيل مزود SessionControls، لذا فإن الوكيل الذي لا يملك واحدًا لا يعلن عن أي منهما. تبقى وسائل النقل البعيدة، ومحددات النماذج، والإضافات التجريبية للبروتوكول غير معلنة. يُرفض أي مطالبة تحمل نوع محتوى لم يعلنه الخادم مع رسالة خطأ وصفية بدلًا من معالجتها جزئيًا. ينبغي للمتصلين التصميم بناءً على كائن القدرات المتفاوض عليه بدلًا من افتراض أن كل تنفيذ ACP يملك السطح نفسه.

التالي

بنية بروتوكول عميل الوكيل - وثائق ADK-Rust | ADK-Rust