إتاحة وكيل ADK-Rust من خلال ACP
استخدم نمط الخادم عندما ينبغي لمحرر أو عميل ACP آخر تشغيل ملفك الثنائي ADK-Rust واستخدام وكيله داخل واجهة برمجة للترميز. تتولى عملية Rust مسؤولية الوكيل، والنموذج، والأدوات، وسير العمل، والجلسات، والذاكرة، وسياسة التشغيل. ولا يرى العميل سوى القدرات ودورة حياة الجلسة المنشورة من خلال ACP.
تثبيت ميزة الخادم
[dependencies]
adk-acp = { version = "2.1.0", features = ["server"] }
بناء وكيل وتقديمه
use adk_acp::server::{AcpServer, AcpServerConfigBuilder};
use adk_session::InMemorySessionService;
use std::sync::Arc;
let config = AcpServerConfigBuilder::new()
.agent(Arc::new(repository_agent))
.session_service(Arc::new(InMemorySessionService::new()))
.agent_name("repository-guide")
.agent_description("Explains and improves this Rust workspace")
.max_sessions(16)
.build()?;
let handle = AcpServer::run(config).await?;
handle.wait().await?;
يستخدم الخادم أداة البناء الرسمية SDK Agent ونقل stdio. وتُكتب حركة
بيانات البروتوكول وحدها إلى stdout؛ لذا اضبط التتبع والتشخيص لاستخدام stderr.
تعيين وقت التشغيل
يتحقق المعالج من cwd المطلق، ويحجز سعة الجلسة، وينشئ جلسة ADK أو
يستأنفها، ثم يشغّل الوكيل المُعدّ. وتُترجم أحداث ADK المُنمّطة إلى
إشعارات session/update ACP أثناء نشاط الطلب.
دورة الحياة المُنفّذة
| ACP العملية | ADK-Rust السلوك |
|---|---|
initialize | يتفاوض بشأن البروتوكول v1 ويُرجع بيانات وصفية دقيقة للتنفيذ والقدرات |
session/new | يتحقق من مسارات مساحة العمل وينشئ جلسة ADK واحدة مستمرة |
session/prompt | يحوّل كتل المحتوى المدعومة (النص، ورابط المورد، والمورد المضمّن، والصورة، والصوت) ويبثّ Runner |
session/load | يعيد تنشيط جلسة محفوظة (مع التحقق من cwd) ويعيد تشغيل محادثتها المخزّنة على شكل إشعارات session/update مرتبة قبل الإكمال |
session/cancel | يلغي استدعاء Runner النشط ويُرجع سبب إيقاف يفيد الإلغاء |
$/cancel_request | يلغي الطلب المطابق JSON-RPC من دون إفساد الجلسة |
session/close | يلغي العمل النشط ويحرر العمليات المملوكة للجلسة |
session/list | يسرد الجلسات المحفوظة المرئية لـ ACP |
session/resume | يعيد الاتصال بالجلسة الأصلية ومساحة العمل |
session/fork | ينشئ جلسة جديدة بمعرّف جلسة جديد انطلاقًا من جلسة محفوظة، مع نسخ سجلها وحالتها ذات الصلة وترك المصدر دون تغيير |
session/set_mode | يتحقق من وضع الجلسة الذي يعلنه SessionControls الخاص بالوكيل ويسجّله، مع إصدار CurrentModeUpdate |
session/set_config_option | يتحقق من قيمة الإعداد التي يعلنها SessionControls الخاص بالوكيل ويسجّلها، مع إصدار ConfigOptionUpdate |
session/delete | يزيل السجل المحفوظ ويحرّر الموارد النشطة |
لا يمكن تشغيل سوى مطالبة واحدة في الجلسة في كل مرة. ويمكن تشغيل جلسات مختلفة
بالتزامن بما يصل إلى max_sessions.
تعيين الأحداث
- يصبح نص النموذج
agent_message_chunk؛ - يصبح محتوى أفكار النموذج
agent_thought_chunk؛ - يصبح محتوى المورد المضمّن موردًا مضمّنًا ACP من النوع
agent_message_chunk؛ - تصبح استدعاءات الدوال ADK تحديثات بدء الأداة ACP مع أداة مستنتجة
kind؛ - تصبح استجابات الدوال تحديثات إكمال الأداة، مع إثرائها بمحتوى النتيجة وأي مواقع ملفات متأثرة، وربطها باستدعاء الأداة الأصلي؛
- تصبح الأحداث التي تحمل بيانات وصفية للاستخدام إشعارات
UsageUpdate(تعدادات الرموز، بالإضافة إلى التكلفة بالدولار الأمريكي عند الإبلاغ عنها)؛ - تصبح الأوامر التي يعلنها الوكيل أمرًا
AvailableCommandsUpdateعند تنشيط الجلسة، ويصبح عنوان الجلسة المسجّلSessionInfoUpdate؛ - تصبح إدخالات الخطة تحديثًا
Plan— يوجد هذا التعيين، لكنه يظل غير نشط إلى أن تكشف بدائية خطة ADK عن إدخالات الخطة؛ - يصبح الإلغاء
StopReason::Cancelled؛ - يصبح الإكمال الطبيعي
StopReason::EndTurn.
تتولى وحدة محتوى مشتركة ملكية تعيين ContentBlock ↔ adk_core::Part
في كلا الاتجاهين. ويُعيَّن محتوى المطالبة للموارد المضمّنة إلى
Part::EmbeddedResource، مع الحفاظ على المصدر URI الاختياري، ونوع MIME،
والمحتويات؛ إذ تُحفظ الموارد النصية حرفيًا، بينما تُرمَّز الموارد الثنائية
بترميز base64 أثناء النقل وتُفك إلى بايتات خام داخليًا. ويُعيَّن محتوى
مطالبة الصور والصوت إلى Part::InlineData، مع الحفاظ على نوع MIME، والبايتات
المفكوكة، والتعليقات التوضيحية، والمصدر URI الاختياري للصورة. وتبقى
هذه الحقول في JSON الخاصة بالجلسة، ويستعيدها session/load. وبما أن معالج
المطالبات يقبل محتوى الموارد المضمّنة والصور والصوت، يعلن الخادم عن
إمكانات المطالبات embedded_context وimage وaudio. ويُرفض أي طلب مطالبة
يحمل نوع محتوى لم يعلنه الخادم، مع إرجاع خطأ وصفي بدلًا من معالجته
جزئيًا.
تحميل السجل وإعادة تشغيله
يستعيد session/load السجل المرئي لجلسة محفوظة عندما يعيد العميل الاتصال.
ويعيد المعالج تنشيط الجلسة بالطريقة نفسها التي يستخدمها session/resume
— إذ يتحقق من أن المستدعي قدّم cwd الأصلي، ويُرجع خطأ يفيد بعدم
العثور على الجلسة عند تقديم معرّف غير معروف — ثم ينفذ عملية إعادة تشغيل.
ويقرأ الأحداث المحفوظة من خلال خدمة الجلسات، ويعيّن كل حدث محفوظ للمستخدم
أو الوكيل أو الفكرة أو الأداة إلى إشعار session/update المناظر له، بالترتيب
الزمني الأصلي، قبل اكتمال طلب التحميل. ويعلن الخادم عن إمكانية load_session
حتى يعرف العميل أنه يستطيع إعادة الاتصال وإعادة بناء عرض المحادثة.
أوضاع الجلسة وخيارات الإعداد والتفرع
يختار الوكيل استخدام عناصر التحكم في الجلسة التفاعلية من خلال توفير SessionControls
عبر AcpServerConfigBuilder::session_controls. يعلن الموفّر عن الأوضاع المتاحة (وهي SessionModeState)، وخيارات
التهيئة (قوائم الاختيار ومفاتيح التبديل)، وأوامر الشرطة المائلة
ACP. يعلن الخادم بالضبط ما يعلنه الموفّر — فالوكيل الذي لا يملك موفّراً
لا يعلن أي أوضاع أو خيارات — ويعرضها في استجابات
session/new وsession/load وsession/resume وsession/fork.
يتحقق session/set_mode من معرّف الوضع المطلوب مقابل المجموعة المُعلنة،
ويسجّله، ويصدر CurrentModeUpdate؛ أما المعرّف غير المعروف فيُرفض ويظل
الوضع الحالي دون تغيير. ويتحقق session/set_config_option من القيمة مقابل
الخيارات المُعلنة للخيار، ويسجّلها، ويصدر
ConfigOptionUpdate؛ ويُرفض أي خيار غير معروف أو قيمة غير صالحة. يستمر كلا
الاختيارين في حالة الجلسة ADK ضمن acp:mode وacp:config:<id>،
وبذلك يظلان محفوظين بعد التحميل والاستئناف والتفرّع.
يُنشئ session/fork فرعاً من جلسة محفوظة: إذ يقرأ الجلسة المصدر، وينشئ
معرّف جلسة جديداً، وينسخ الأحداث المخزّنة والحالة ذات الصلة
(cwd، والأدلة الإضافية، والوضع، والتهيئة) إليه، ثم يعيد المعرّف الجديد. ويظل
السجل المحفوظ لجلسة المصدر دون تغيير حرفياً. ويعيد التفرّع لمعرّف جلسة
غير معروف خطأ يفيد بعدم العثور على الجلسة. ويعلن الخادم قدرة الجلسة
fork لأن معالجها مسجّل.
عند تفعيل الجلسة، يصدر الخادم أيضاً AvailableCommandsUpdate لأي أوامر يعلنها
الموفّر (ولا يصدر شيئاً عندما لا يعلن أي أوامر)، وSessionInfoUpdate يحمل عنوان الجلسة
عندما يكون مسجّلاً ضمن acp:title (ويُضبط عبر set_session_title). ويوجد تعيين
لتحديث Plan، لكنه يظل خاملاً إلى أن يعرض عنصر أولي للخطة
ADK إدخالات الخطة.
خوادم MCP التي يوفّرها العميل
قد يتضمن العميل خوادم stdio MCP في session/new أو session/resume.
يتحقق الخادم من الأسماء والأوامر والوسائط وإدخالات البيئة قبل
بدء عملية. ثم:
- يبدأ كل عملية فرعية في مساحة عمل الجلسة؛
- يطبّق مصافحة بدء تشغيل محددة المدة؛
- يغلّف الاتصال باعتباره ADK
McpToolset؛ - يحقن مجموعة الأدوات في استدعاء Runner هذا؛
- يلغي خدمات MCP عند الإغلاق أو الحذف أو فشل بدء التشغيل أو إيقاف تشغيل الخادم.
تُحل مجموعات الأدوات الخاصة بنطاق الاستدعاء حاليًا بواسطة LlmAgent و
CodeActAgent. ولا يعلن الخادم عن عمليات نقل HTTP وSSE MCP الاختيارية.
قرارات الاستمرارية
يُعد InMemorySessionService مناسبًا لعملية محرر محلية وللاختبارات. استخدم
خدمة دائمة عندما يتعين أن تبقى الجلسات بعد إعادة تشغيل العمليات. يتحقق
الاستئناف من أن المستدعي يقدّم cwd الأصلي؛ ولا يمكن إعادة إرفاق جلسة
بمشروع مختلف دون إشعار.
حد الموافقة على الأدوات
يربط الخادم تأكيدات الأدوات ADK بطلبات الأذونات الأصلية ACP.
عندما يتوقف الوكيل المكوّن على ToolConfirmationRequest أثناء دورة مطالبة
— ويظهر ذلك على event.actions.tool_confirmation عندما ينتظر وكيل موافقة بشرية
على استدعاء أداة — يرسل الخادم طلب session/request_permission
يصف الأداة ووسائطها، وينتظر نتيجة العميل، ثم
يستأنف التنفيذ بالقرار المطابق. تتحول الموافقة إلى سماح، بينما يتحول الرفض
أو الإلغاء، كلاهما، إلى رفض، ولذلك لا ينفّذ الطلب الملغى الأداة مطلقًا. ترتبط
كل نتيجة بالاستدعاء الدقيق من خلال معرّف استدعاء الدالة الخاص به، وتُمرّر مرة أخرى
إلى المشغّل عبر RunConfig::tool_confirmation_decisions.
يصدر session/request_permission المتداخل من المهمة التي تتولى بالفعل معالجة session/prompt الخارجي، والتي تم تشغيلها عبر ConnectionTo::spawn، ولذلك لا يحظر حلقة توزيع الاتصال، وتظل استجابة المطالبة الخارجية مكتملة. لم يتكرر القلق السابق من أن SDK الرسمي الخاص بـ Rust يفقد استجابة المطالبة الخارجية بعد طلب ثنائي الاتجاه متداخل مع تدفق الإيقاف المؤقت/الاستئناف هذا؛ إذ تغطيه اختبارات التشغيل البيني داخل الذاكرة.
يظل تفويض الأدوات المملوك للخادم، والأدوات للقراءة فقط، وRBAC، والضوابط الوقائية، ومقاطعات سير العمل متاحًا عندما يجب أن تحدث الموافقة بالكامل داخل عملية ADK-Rust. كما أن مسار الأذونات من جانب العميل لوكلاء ACP الخارجيين مطبق بالكامل أيضًا.
النشر بأمان
- شغّل الملف الثنائي باستخدام مساحة عمل المشروع المقصودة.
- تعامل مع
cwdوالجذور الإضافية باعتبارها سياقًا، لا عزلًا على مستوى نظام التشغيل. - طبّق
adk-sandboxأو حاوية أو حدًا آخر بين العمليات للمطالبات والأوامر غير الموثوقة. - احتفظ ببيانات اعتماد النموذج وMCP في مخزن أسرار خاص بالعميل أو في بيئة العملية.
- لا تكتب مطلقًا الشعارات أو كائنات التصحيح أو السجلات إلى stdout الخاص بالبروتوكول.
- استخدم
SessionServiceدائمًا عندما يجب أن يستمر الاستئناف بعد إعادة تشغيل العملية. - عيّن حدًا زمنيًا finite للجلسة وأغلق الجلسات غير النشطة.
تتضمن حزمة acp_server القابلة للتشغيل وكيلًا مدعومًا بـ Gemini، وأدوات قراءة مقيّدة بمساحة العمل، وتتبع stderr، وتهيئة عملية المحرر.