أدوات واجهة المستخدم

تُمكّن حزمة adk-ui وكلاء الذكاء الاصطناعي من إنشاء واجهات مستخدم غنية ديناميكيًا من خلال استدعاءات الأدوات. يمكن للوكلاء عرض النماذج والبطاقات والتنبيهات والجداول والمخططات وغير ذلك — كل ذلك من خلال API آمن من حيث الأنواع بلغة Rust، والذي يُسلسل إلى JSON لاستخدامه في الواجهة الأمامية.

ما ستبنيه

وكيل واجهة المستخدم ADK

المفاهيم الأساسية:

  • النماذج - جمع إدخالات المستخدم باستخدام أنواع مختلفة من الحقول
  • البطاقات - عرض المعلومات باستخدام أزرار الإجراءات
  • الجداول - تقديم البيانات المنظمة في صفوف وأعمدة
  • المخططات - تمثيل البيانات بصريًا باستخدام المخططات الشريطية والخطية والمساحية والدائرية
  • التنبيهات - عرض الإشعارات ورسائل الحالة
  • مربعات الحوار - مربعات حوار التأكيد والتفاعلات المركّزة
  • الإشعارات المنبثقة - إشعارات حالة موجزة
  • التشغيل البيني للبروتوكولات - إصدار واجهة المستخدم بصيغة A2UI أو AG-UI أو حمولات تطبيقات MCP

مثال: لوحة معلومات التحليلات

تحليلات واجهة المستخدم ADK

مثال: نموذج التسجيل

تسجيل واجهة المستخدم ADK


آلية العمل

┌─────────────────────────────────────────────────────────────────────────────┐
│ STEP 1: User requests something                                             │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   User: "I want to register for an account"                                 │
│                                                                             │
│                              ↓                                              │
│                                                                             │
│   ┌──────────────────────────────────────┐                                  │
│   │         AI AGENT (LLM)              │                                  │
│   │  "I should show a registration form" │                                  │
│   └──────────────────────────────────────┘                                  │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────────────────┐
│ STEP 2: Agent calls render_form tool                                        │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   📞 Tool Call: render_form({                                               │
│     title: "Registration",                                                  │
│     fields: [                                                               │
│       {name: "email", type: "email"},                                       │
│       {name: "password", type: "password"}                                  │
│     ]                                                                       │
│   })                                                                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────────────────┐
│ STEP 3: Frontend renders the form                                           │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   ┌─────────────────────────────────────────────────┐                       │
│   │  📋 Registration                               │                       │
│   │  ────────────────────────────────────────────  │                       │
│   │  Email:    [________________________]          │                       │
│   │  Password: [________________________]          │                       │
│   │                                                │                       │
│   │  [           Register           ]              │                       │
│   └─────────────────────────────────────────────────┘                       │
│                                                                             │
│   ✅ User sees an interactive form, fills it out, clicks Register           │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────────────────┐
│ STEP 4: Form submission sent back to agent                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│   📩 Event: {                                                               │
│     type: "form_submit",                                                    │
│     data: { email: "user@example.com", password: "***" }                    │
│   }                                                                         │
│                                                                             │
│   Agent: "Great! I'll process your registration and show a success alert"  │
│                                                                             │
│   📞 Tool Call: render_alert({                                              │
│     title: "Registration Complete!",                                        │
│     variant: "success"                                                      │
│   })                                                                        │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘

نظرة عامة

تتيح أدوات واجهة المستخدم للوكلاء ما يلي:

  • جمع إدخالات المستخدم من خلال نماذج ديناميكية تدعم مناطق النص
  • عرض المعلومات باستخدام البطاقات والتنبيهات والإشعارات
  • تقديم البيانات في جداول ومخططات تفاعلية (Recharts)
  • عرض حالات التقدم والتحميل (المؤشر، والهيكل العظمي)
  • إنشاء تخطيطات لوحات المعلومات باستخدام مكونات متعددة
  • طلب تأكيد المستخدم عبر مربعات الحوار
  • عرض إشعارات منبثقة لتحديثات الحالة

البدء السريع

أضف إلى Cargo.toml:

[dependencies]
adk-ui = { git = "https://github.com/zavora-ai/adk-ui" }
adk-agent = "2.1.0"
adk-model = "2.1.0"

الاستخدام الأساسي

use adk_rust::prelude::*;
use adk_ui::UiToolset;
use std::sync::Arc;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let model = Arc::new(GeminiModel::from_env("gemini-3.7-flash")?);

    // Get all 10 UI tools
    let ui_tools = UiToolset::all_tools();

    // Create AI agent with UI tools
    let mut builder = LlmAgentBuilder::new("ui_agent")
        .model(model)
        .instruction(r#"
            You are a helpful assistant that uses UI components to interact with users.
            Use render_form for collecting information.
            Use render_card for displaying results.
            Use render_alert for notifications.
            Use render_modal for confirmation dialogs.
            Use render_toast for brief status messages.
        "#);

    for tool in ui_tools {
        builder = builder.tool(tool);
    }

let agent = builder.build()?;
Ok(())
}

A2UI JSONL (render_screen / render_page / render_kit)

تُصدر هذه الأدوات JSONL الإصدار 0.9 من A2UI للتوافق مع عارضي A2UI.

render_screen (سطح واحد)

{
  "surface_id": "main",
  "components": [
    { "id": "root", "component": "Column", "children": ["title", "cta"] },
    { "id": "title", "component": "Text", "text": "Welcome", "variant": "h1" },
    { "id": "cta_label", "component": "Text", "text": "Continue", "variant": "body" },
    { "id": "cta", "component": "Button", "child": "cta_label", "action": { "event": { "name": "continue" } } }
  ]
}

render_page (صفحة متعددة الأقسام)

{
  "title": "Release Notes",
  "description": "Highlights for the latest launch.",
  "sections": [
    {
      "heading": "What’s new",
      "body": "Three big improvements shipped this week.",
      "bullets": ["Faster onboarding", "Better search", "New dashboards"],
      "actions": [{ "label": "View details", "action": "view_details", "variant": "borderless" }]
    }
  ]
}

render_kit (الفهرس + الرموز + القوالب)

{
  "name": "Fintech Pro",
  "version": "0.1.0",
  "brand": { "vibe": "trustworthy", "industry": "fintech" },
  "colors": { "primary": "#2F6BFF" },
  "typography": { "family": "Source Sans 3" },
  "templates": ["auth_login", "dashboard"]
}

استخدم مُصيّر React لاستهلاك JSONL ‏A2UI:

import {
  A2uiStore,
  A2uiSurfaceRenderer,
  applyParsedMessages,
  parseJsonl,
} from "@zavora-ai/adk-ui-react";

const store = new A2uiStore();
const parsed = parseJsonl(jsonl);
applyParsedMessages(store, parsed);

export function App() {
  return <A2uiSurfaceRenderer store={store} surfaceId="main" />;
}

الأدوات المتاحة

render_form

صيّر نماذج تفاعلية لجمع إدخالات المستخدم.

{
  "title": "Registration Form",
  "description": "Create your account",
  "fields": [
    {"name": "username", "label": "Username", "type": "text", "required": true},
    {"name": "email", "label": "Email", "type": "email", "required": true},
    {"name": "password", "label": "Password", "type": "password", "required": true},
    {"name": "newsletter", "label": "Subscribe to newsletter", "type": "switch"}
  ],
  "submit_label": "Register"
}

يُصيّر كالتالي:

┌─────────────────────────────────────────────────┐
│  📋 Registration Form                          │
│  Create your account                           │
│  ─────────────────────────────────────────────  │
│                                                │
│  Username *                                    │
│  ┌─────────────────────────────────────────┐   │
│  │                                         │   │
│  └─────────────────────────────────────────┘   │
│                                                │
│  Email *                                       │
│  ┌─────────────────────────────────────────┐   │
│  │                                         │   │
│  └─────────────────────────────────────────┘   │
│                                                │
│  Password *                                    │
│  ┌─────────────────────────────────────────┐   │
│  │ ••••••••                                │   │
│  └─────────────────────────────────────────┘   │
│                                                │
│  Subscribe to newsletter  [○]                  │
│                                                │
│  ┌─────────────────────────────────────────┐   │
│  │             Register                    │   │
│  └─────────────────────────────────────────┘   │
│                                                │
└─────────────────────────────────────────────────┘

أنواع الحقول: text، email، password، number، date، select، multiselect، switch، slider، textarea

render_card

اعرض بطاقات معلومات مع أزرار إجراءات اختيارية.

{
  "title": "Order Confirmed",
  "description": "Order #12345",
  "content": "Your order has been placed successfully. Expected delivery: Dec 15, 2025.",
  "actions": [
    {"label": "Track Order", "action_id": "track", "variant": "primary"},
    {"label": "Cancel", "action_id": "cancel", "variant": "danger"}
  ]
}

أنواع الأزرار: primary، secondary، danger، ghost، outline

render_alert

اعرض الإشعارات ورسائل الحالة.

{
  "title": "Payment Successful",
  "description": "Your payment of $99.00 has been processed.",
  "variant": "success"
}

الأنواع: info، success، warning، error

render_confirm

اطلب تأكيد المستخدم قبل تنفيذ الإجراءات.

{
  "title": "Delete Account",
  "message": "Are you sure you want to delete your account? This action cannot be undone.",
  "confirm_label": "Delete",
  "cancel_label": "Keep Account",
  "variant": "danger"
}

render_table

اعرض البيانات الجدولية.

{
  "title": "Recent Orders",
  "columns": [
    {"header": "Order ID", "accessor_key": "id"},
    {"header": "Date", "accessor_key": "date"},
    {"header": "Amount", "accessor_key": "amount"},
    {"header": "Status", "accessor_key": "status"}
  ],
  "data": [
    {"id": "#12345", "date": "2025-12-10", "amount": "$99.00", "status": "Delivered"},
    {"id": "#12346", "date": "2025-12-11", "amount": "$149.00", "status": "Shipped"}
  ]
}

render_chart

أنشئ تصورات مرئية للبيانات.

{
  "title": "Monthly Sales",
  "chart_type": "bar",
  "x_key": "month",
  "y_keys": ["revenue", "profit"],
  "data": [
    {"month": "Jan", "revenue": 4000, "profit": 2400},
    {"month": "Feb", "revenue": 3000, "profit": 1398},
    {"month": "Mar", "revenue": 5000, "profit": 3800}
  ]
}

أنواع المخططات: bar، line، area، pie

render_progress

اعرض تقدّم المهام مع خطوات اختيارية.

{
  "title": "Installing Dependencies",
  "value": 65,
  "description": "Installing package 13 of 20...",
  "steps": [
    {"label": "Download", "completed": true},
    {"label": "Extract", "completed": true},
    {"label": "Install", "current": true},
    {"label": "Configure", "completed": false}
  ]
}

render_layout

أنشئ تخطيطات لوحات معلومات متعددة الأقسام.

{
  "title": "System Status",
  "description": "Current system health overview",
  "sections": [
    {
      "title": "Services",
      "type": "stats",
      "stats": [
        {"label": "API Server", "value": "Healthy", "status": "operational"},
        {"label": "Database", "value": "Degraded", "status": "warning"},
        {"label": "Cache", "value": "Down", "status": "error"}
      ]
    },
    {
      "title": "Recent Errors",
      "type": "table",
      "columns": [{"header": "Time", "key": "time"}, {"header": "Error", "key": "error"}],
      "rows": [{"time": "10:30", "error": "Connection timeout"}]
    }
  ]
}

أنواع الأقسام: stats، table، chart، alert، text

render_modal

اعرض مربعات حوار منبثقة للتأكيدات أو التفاعلات المركّزة.

{
  "title": "Confirm Deletion",
  "message": "Are you sure you want to delete this item? This action cannot be undone.",
  "size": "medium",
  "closable": true,
  "confirm_label": "Delete",
  "cancel_label": "Cancel",
  "confirm_action": "delete_confirmed"
}

الأحجام: small، medium، large، full

render_toast

اعرض إشعارات toast موجزة لتحديثات الحالة.

{
  "message": "Settings saved successfully",
  "variant": "success",
  "duration": 5000,
  "dismissible": true
}

الأنواع: info، success، warning، error

الأدوات المُرشّحة

حدّد الأدوات التي يحتاجها وكيلك فقط:

let toolset = UiToolset::new()
    .without_chart()      // Disable charts
    .without_table()      // Disable tables
    .without_progress()   // Disable progress
    .without_modal()      // Disable modals
    .without_toast();     // Disable toasts

// Or use forms only
let forms_only = UiToolset::forms_only();

التعامل مع أحداث واجهة المستخدم

عندما يتفاعل المستخدمون مع واجهة المستخدم المُصيّرة (إرسال النماذج، والنقر على الأزرار)، تُرسل الأحداث مرة أخرى إلى الوكيل:

use adk_ui::{UiEvent, UiEventType};

// UiEvent structure
pub struct UiEvent {
    pub event_type: UiEventType,  // FormSubmit, ButtonClick, InputChange
    pub action_id: Option<String>,
    pub data: Option<HashMap<String, Value>>,
}

// Convert to message for agent
let message = ui_event.to_message();

بث تحديثات واجهة المستخدم

للحصول على تحديثات واجهة المستخدم في الوقت الفعلي، استخدم UiUpdate لتصحيح المكونات حسب المعرّف:

use adk_ui::{UiUpdate, UiOperation};

let update = UiUpdate {
    target_id: "progress-bar".to_string(),
    operation: UiOperation::Patch,
    payload: Some(Component::Progress(Progress {
        id: Some("progress-bar".to_string()),
        value: 75,
        label: Some("75%".to_string()),
    })),
};

العمليات: Replace، Patch، Append، Remove

مخطط المكوّن

تدعم جميع أنواع المكوّنات البالغ عددها 28 نوعًا حقول id الاختيارية لتحديثات البث:

العناصر الأساسية: Text، Button، Icon، Image، Badge
المدخلات: TextInput، NumberInput، Select، MultiSelect، Switch، DateInput، Slider، Textarea
التخطيطات: Stack، Grid، Card، Container، Divider، Tabs
البيانات: Table، List، KeyValue، CodeBlock
التصور المرئي: Chart (شريطي، خطي، مساحي، دائري عبر Recharts)
التغذية الراجعة: Alert، Progress، Toast، Modal، Spinner، Skeleton

عميل React

يتوفر تطبيق React مرجعي في مستودع adk-ui المستقل:

npm install @zavora-ai/adk-ui-react

يتضمن عميل React ما يلي:

  • أنواع TypeScript المطابقة لمخطط Rust
  • مُصيّر للمكوّنات لجميع الأنواع البالغ عددها 28 نوعًا
  • تكامل Recharts للمخططات التفاعلية
  • دعم عرض Markdown
  • دعم الوضع الداكن
  • معالجة إرسال النماذج
  • مكوّنات Modal وToast

البنية

Agent ──[render_* tool]──> UiResponse (JSON)
                              │
                              │ SSE
                              ▼
                         Client (React)
                              │
                              └──> UiEvent (user action) ──> Agent

التشغيل البيني للبروتوكول

تدعم جميع أدوات العرض البالغ عددها 13 أداة مخرجات مدركة للبروتوكول من خلال الوسيطة protocol:

البروتوكولالوصف
a2uiأسطح JSONL المتوافقة مع A2UI v0.9 (الافتراضية لـ render_screen وrender_page)
ag_uiدعم Hybrid AG-UI: أغلفة التوافق افتراضيًا، بالإضافة إلى نقل وقت تشغيل أصلي للبروتوكول لعملاء adk-server
mcp_appsتوافق حمولات التطبيقات MCP مع موارد ui://، ومساعدات جسر إضافية، وتدفقات الإشعارات، وحقول طلبات وقت التشغيل، ومحوّلات HTML/الموارد

عند حذف protocol، تستخدم الأدوات تنسيق الإخراج الافتراضي الخاص بها (UiResponse JSON القديم لمعظم الأدوات، وA2UI لـ render_screen/render_page/render_kit).

مثال على اختيار البروتوكول:

{
  "protocol": "mcp_apps",
  "mcp_apps": {
    "resource_uri": "ui://demo/surface"
  }
}

محولات التشغيل البيني

يتضمن adk-ui بدائيات المحولات لتحويل البروتوكولات:

  • A2uiAdapter — يحوّل الواجهات الأساسية إلى JSONL الخاص بـ A2UI
  • AgUiAdapter — يحوّل إلى حمولات أحداث AG-UI
  • McpAppsAdapter — يحوّل إلى حمولات موارد تطبيقات MCP

تطبّق هذه المحولات سمة UiProtocolAdapter المشتركة لضمان التحويل المتسق عبر جميع الأدوات.

الجدول الزمني للإيقاف

يحمل ملف تعريف وقت التشغيل القديم adk_ui بيانات وصفية للإيقاف:

التاريخالمحطة الرئيسية
2026-02-07الإعلان عن الإهمال
2026-12-31الموعد المستهدف للإيقاف

الاستبدالات: a2ui، ag_ui، mcp_apps

تُعرَض هذه البيانات الوصفية من خلال ثوابت UI_PROTOCOL_CAPABILITIES، وتُوفَّر بواسطة adk-server في /api/ui/capabilities. كما تستجيب القدرات أيضًا بـ implementationTier وspecTrack وsummary وlimitations، بحيث يمكن للعملاء التمييز بين المجموعات الفرعية الهجينة أو المتوافقة وبين الدعم الأصلي الكامل للبروتوكول.

عندما تكون adk-server هي الحد الفاصل المواجه للمضيف، فإنها تكشف أيضًا عن مساعدات جسر إضافية لـ MCP Apps في /api/ui/initialize و/api/ui/message و/api/ui/update-model-context و/api/ui/notifications/poll و/api/ui/notifications/resources-list-changed و/api/ui/notifications/tools-list-changed. تحافظ نقاط النهاية هذه على عقود وقت التشغيل الحالية لـ ADK، وتقبل إما أجسام طلبات مباشرة أو أغلفة شبيهة بـ JSON-RPC تحتوي على أساليب ui/....

بالنسبة إلى مستهلكي وقت التشغيل، تدعم adk-server أيضًا ما يلي:

  • x-adk-ui-transport: protocol_native أو uiTransport: "protocol_native" لتسلسل SSE الأصلي لـ AG-UI
  • مدخلات الطلب ثنائية المسار لـ AG-UI عبر input / agUiInput إلى جانب newMessage الحالية
  • أغلفة جسر Apps من MCP داخل /api/run_sse عبر mcpAppsInitialize وmcpAppsRequest وmcpAppsInitialized

هذه الإضافات اختيارية. يواصل مستهلكو /api/run و/api/run_sse الحاليون تلقي الغلاف العام ADK، ما لم يطلبوا صراحةً وضع نقل أصلي لـ AG-UI.

بالنسبة إلى استجابات أدوات Apps الخاصة بـ MCP والمملوكة لإطار العمل، تكشف adk-server::ui_types الآن عن:

  • McpUiBridgeSnapshot لحالة جسر المضيف/التطبيق المكتوبة
  • McpUiToolResult لغلاف الاستجابة الإضافي
  • McpUiToolResultBridge لبيانات الجسر الوصفية (protocolVersion وstructuredContent وhostInfo وhostCapabilities وhostContext وappInfo وappCapabilities وinitialized)

يُفضَّل استخدام McpUiBridgeSnapshot::build_tool_result(...) عند ترقية حالة الجسر/الجلسة إلى استجابة أداة. يؤدي ذلك إلى توحيد شكل نتيجة الأداة مع الحفاظ على resourceUri وبدائل html المضمّنة للمضيفين الذين يركزون على التوافق.

بالنسبة إلى تعيينات المضيف المضمّن أو المضيف في المتصفح، يتوافق جسر HTTP الإضافي مع تدفقات المضيف/التطبيق كما يلي:

  • ui/initialize -> /api/ui/initialize
  • ui/message -> /api/ui/message
  • ui/update-model-context -> /api/ui/update-model-context
  • notifications/resources/list_changed -> /api/ui/notifications/resources-list-changed
  • notifications/tools/list_changed -> /api/ui/notifications/tools-list-changed
  • إشعارات المضيف الموضوعة في قائمة الانتظار -> /api/ui/notifications/poll

تُعد نقاط نهاية الجسر /api/ui/* المباشرة مسار دورة الحياة المفضّل لمضيفي MCP Apps. وتظل حقول طلبات MCP Apps على جانب وقت التشغيل متاحة كمسار توافق إضافي للعملاء المختلطين أو العملاء الأقدم.

أمثلة

يحتوي مستودع adk-ui المستقل على أمثلة واجهة المستخدم القابلة للتشغيل:

المثالالوصفأمر التشغيل
ui_agentعرض توضيحي لوحدة التحكمcargo run --bin ui_agent
ui_serverخادم HTTP مع SSEcargo run --bin ui_server
ui_react_clientواجهة React الأماميةcd ui_react_client && npm run dev

شغّل تلك الأمثلة من مستودع adk-ui حتى تبقى حزمتا Rust وReact على خط الإصدار نفسه.

مطالبات نموذجية

اختبر أدوات واجهة المستخدم باستخدام هذه المطالبات:

# Forms
"I want to register for an account"
"Create a contact form"
"Create a feedback form with a comments textarea"

# Cards
"Show me my profile"
"Display a product card for a laptop"

# Alerts
"Show a success message"
"Display a warning about expiring session"

# Modals
"I want to delete my account" (shows confirmation modal)
"Show a confirmation dialog before submitting"

# Toasts
"Show a success toast notification"
"Display an error toast"

# Tables
"Show my recent orders"
"List all users"

# Charts
"Show monthly sales chart"
"Display traffic trends as a line chart"
"Show revenue breakdown as a pie chart"

# Progress & Loading
"Show upload progress at 75%"
"Display a loading spinner"
"Show skeleton loading state"

# Dashboards
"Show system status dashboard"

السابق: ← أدوات المتصفح | التالي: أدوات MCP →

أدوات واجهة المستخدم - وثائق ADK-Rust | ADK-Rust