أتمتة سطح المكتب المُدارة
adk-computer-use هي طبقة حوكمة فوق خادم أتمتة سطح المكتب computer-use-mcp. لا تقوم بأي تنفيذ بنفسها: بل ترتّب الملاحظة، والموافقة، والتعديل، والتحقق على شكل رسم بياني حتمي، وتفحص ما يعيده وقت التشغيل الخارجي.
ربط الاستجابة
يُعدّ وقت التشغيل الخارجي هو المرجع المعتمد، لكن تتم مراجعة استجاباته محليًا قبل دخولها إلى حالة الرسم البياني. تُنفَّذ عمليات الفحص في الرسم البياني المرجعي لكل تطبيق ComputerUseRuntime، ويعيد محول MCP تنفيذها عند حد الاستدعاء المباشر. يثبت إلغاء التسلسل المُمَنعَن البنية، لا المصدر — إذ إن ControlLease وTargetReservation وExecutionReceipt لا تملك مُنشئًا يفرض الثوابت، لذا فإن كائنًا سليم البنية ينتمي إلى جلسة مختلفة يُحلَّل بشكل صحيح.
يُربط كل ردّ من جديد بالطلب الذي أنشأه:
| الاستجابة | تم التحقق منها مقابل الظرف |
|---|---|
ControlLease | session_id، principal_id، agent_id، execution_mode، الحالة النشطة، expires_at غير منتهٍ، الميزانية المتبقية (actions_used < action_budget)، والهدف ضمن boundaries |
TargetReservation | session_id، principal_id، agent_id، execution_group_id، intent_id == action_id، الحالة النشطة، expires_at غير منتهٍ، ونطاق الهدف الدقيق للتطبيق/النافذة |
ExecutionReceipt | session_id، action_id، وaction_digest مقابل args_digest الخاص بالظرف |
يؤدي عدم التطابق إلى ComputerUseError::IdentityMismatch مع تسمية الحقل، ويُرفَض الرد بدلاً من تخزينه.
use adk_computer_use::runtime::binding::validate_lease;
// Refuses a lease that is well-formed but belongs to another session.
validate_lease(&lease, &envelope)?;
ملاحظة: الملخّص هو أقوى ربط متاح.
args_digestهو ما تم منح الموافقة عليه، لذا فإن إيصالًا يحمل ملخّصًا مختلفًا يصف عملًا مختلفًا حتى عندما تتطابق كل المعرفات.
يُعامَل الحقل الاختياري الذي يعود غائبًا على أنه نقص في التحديد، لا تناقضًا؛ أمّا الحقل الموجود والمختلف فهو عدم تطابق.
إعادة التحقق وقت التنفيذ
المعاينة ليست سلطة للتعديل. يعيد الرسم البياني المرجعي التحقق من صحة جميع مدخلات التعديل في عقدة execute مباشرةً قبل استدعاء execute_action:
| المدخل | فحص فوري |
|---|---|
ActionEnvelope | طوابع زمنية RFC 3339، نافذة صلاحية موجبة، وnow < expires_at |
ControlLease | الهوية، الوضع، الحالة النشطة، الميزانية المتبقية، انتهاء الصلاحية، وحدود الهدف |
TargetReservation | الهوية، نية الإجراء، الحالة النشطة، انتهاء الصلاحية، ونطاق الهدف الدقيق |
| الموافقة | المسار، ملخص الإجراء، ملخص السياسة، ومصدر تفويض واحد بالضبط (grantId أو الموافقة المحتفظ بها في وقت التشغيل) |
يتم أيضًا تشغيل فحص الظرف عند عودة المعاينة، لذلك لا تصل المعاينة التي انتهت صلاحيتها بالفعل إلى الحجز أو الموافقة. ويُعاد تشغيله أثناء التنفيذ لأن مقاطعة الموافقة أو حجز الهدف أو الحصول على الإيجار يمكن أن يستهلك نافذة الصلاحية المتبقية.
ComputerUseMcpRuntime يحتفظ بالظرف نفسه الذي أرجعته preview_action. يتم رفض استدعاء مباشر لـ execute_action إذا تغيّر أي
حقل في الظرف بعد المعاينة، حتى عندما يظل معرّف الإجراء مطابقًا.
بالنسبة لاستئناف نقطة التفتيش، يخزّن الرسم البياني معاينة وقت التشغيل في قناة حالة للإضافة فقط. تتطلب الموافقة والتنفيذ أن تحتوي تلك القناة على معاينة واحدة فقط تطابق المعاينة النشطة. يمكن لمدخلات الاستئناف إضافة حالة ولكن لا يمكنها استبدال القيمة المُسجَّلة في نقطة التفتيش: إن محاولة الاستبدال تنشئ إدخالًا ثانيًا وتفشل قبل الحجز أو التعديل.
تنظيف الحجز
بمجرد قبول الحجز، تحاول كل المسارات النهائية تحريره:
- فشل الحصول على الإيجار أو التفويض أو التحقق أو التنفيذ أو الاستلام أو التحقق النهائي؛
- التحقق النهائي الناجح؛ و
- فشلات التحقق من الحجز أو التسلسل عندما كانت بيئة التشغيل قد أرجعت حجزًا.
يظل الفشل الأساسي هو الأساسي عندما ينجح التنظيف. وإذا فشل التنظيف أيضًا، يعيد الرسم البياني خطأً واحدًا حتميًا يحتوي على كلا الفشلين. يُعاد فشل التنظيف بعد تحقق ناجح بخلاف ذلك على أنه خطأ بدلًا من إخفائه.
التحقق ليس التزامًا
ComputerUseRuntime::verify تُرجع VerificationOutcome، لا قيمة منطقية:
| النتيجة | المعنى | is_verified() | is_committed() | status() |
|---|---|---|---|---|
Verified | تمت ملاحظة أن الشرط اللاحق المُعلن متحقق | true | true | completed |
CommittedUnverified | نفّذ وقت التشغيل الإجراء؛ لا توجد أدلة على الشرط اللاحق | false | true | committed_unverified |
Failed | غير مُعتمد، أو أن الأدلة تتعارض مع الشرط اللاحق | false | false | verification_failed |
تكتب العقدة verify في الرسم البياني verified وcommitted وresult.verificationDetail
تشرح أي شيء يقلّ عن Verified.
مهم: الإيصال المُسجَّل هو تأكيد بأن الإجراء قد تم قبوله وتنفيذه. وهو ليس دليلاً على أن الأثر المقصود قد حدث. كانت
verifyتُرجع سابقًاreceipt.status == Committed، والتي كانت تُبلِغ عن إجراء مُسجَّل لكنه غير فعّال على أنه مكتمل — من عقدة مُعنونة "verify".
ما الذي يُعدّ دليلاً
بالنسبة إلى شرط لاحق يعلن عن ملخّص تجزئة (valueDigest، contentDigest)، تتطلب عملية التحقق
وجود verification.observedDigest على نتيجة الإيصال يطابقه. بالنسبة إلى شرط لاحق
يعلن الوجود فقط، يلزم وجود verification.satisfied: true صريح.
| دليل الاستلام | النتيجة |
|---|---|
verification.satisfied: false | Failed — ملاحظة سلبية صريحة |
observedDigest يطابق الملخص المتوقع | Verified |
يختلف observedDigest | Failed |
لا يوجد كائن verification | CommittedUnverified |
verification موجود، لا يوجد observedDigest، يُتوقع digest | CommittedUnverified |
غياب الدليل لا يُعامَل أبدًا على أنه دليل على النجاح. إذا تحققت computer-use-mcp قبل إصدار إيصال، فذلك هو عقدها؛ هذا المهايئ لا يفترض ذلك.
حدود الإيجار
يُرفض الإيجار ما لم تتحقق جميع الشروط التالية:
| التحقق | يُرفض عندما |
|---|---|
| انتهاء الصلاحية | expires_at في الماضي، أو لا يمكن تحليلها وفق RFC 3339 |
| الميزانية المتبقية | actions_used >= action_budget |
| حدّ الهدف | غلاف target.app_id غير موجود في boundaries.app_ids غير فارغ |
| حدّ النافذة | غلاف target.window_id غير موجود في boundaries.window_ids غير فارغ |
تعني الحدود الفارغة "غير مُحددة النطاق" وتخوّل أي هدف — إن غياب القيد ليس قيدًا على لا شيء.
مهم: تحققت النسخة الأولى من هذا المصدّق من
action_budget == 0، وهو إجمالي الميزانية، لذا اجتازت رسالة الإيجار ذاتaction_budget: 1, actions_used: 1مع تخويل لا شيء. كما أنها لم تقرأ أبدًاexpires_atأوboundaries، لذلك قُبل كلٌّ من رسالة إيجار منتهية الصلاحية ورسالة إيجار محددة لتطبيق مختلف. يُرفض انتهاء الصلاحية غير القابل للتحليل بدلًا من تجاهله: رسالة الإيجار التي لا يمكن إثبات صلاحيتها ليست صالحة.