अपने ऐप्लिकेशन में A2UI की सतहें रेंडर करना

Jetpack Compose के एजेंट-टू-यूज़र इंटरफ़ेस (A2UI) रेंडरर का इस्तेमाल करते समय, एआई एजेंट ऐसे मैसेज भेजता है जिनमें यूज़र इंटरफ़ेस (यूआई) स्ट्रक्चर, कॉम्पोनेंट प्रॉपर्टी, और डेटा अपडेट के बारे में जानकारी होती है. इन इंटरफ़ेस को अपने ऐप्लिकेशन में नेटिव तौर पर दिखाने के लिए, आपको अपने ऐप्लिकेशन की Jetpack Compose हाइरार्की में A2UI सर्फ़ेस को होस्ट और रेंडर करना होगा.

Compose A2UI रेंडरर, मैसेज पार्स करने, स्नैपशॉट की स्थिति को मैनेज करने, और ऐनिमेशन वाली सतह की स्थिति में बदलाव करने के लिए कोऑर्डिनेट करता है. कोर रेंडरर, किसी खास डिज़ाइन सिस्टम से स्वतंत्र होता है. हालांकि, यह उपलब्ध कराए गए बुनियादी कैटलॉग के ज़रिए, Material Design 3 के साथ इंटिग्रेशन की सुविधा देता है.

Compose की मदद से बनाई गई डेटा लेयर को शुरू करना

A2UI रेंडरर, आपके ऐप्लिकेशन के डेटा लेयर में स्नैपशॉट-अवेयर स्टेट के साथ काम करता है. इससे आपके ऐप्लिकेशन का यूज़र इंटरफ़ेस (यूआई), एजेंट से मिलने वाले इंक्रीमेंटल अपडेट पर प्रतिक्रिया दे पाता है. यह सुविधा जोड़ने के लिए, अपने ViewModel में A2uiMessageParser और A2uiMessageProcessor फ़ैक्ट्री फ़ंक्शन का इस्तेमाल करके, पार्सर और प्रोसेसर को शुरू करें. इसके लिए, यहां दिया गया कोड स्निपेट देखें:

class AgenticUiViewModel : ViewModel() {
    // Create a parser that leverages the built-in JSON parser.
    private val parser = A2uiMessageParser()

    // Create an A2UI message processor with your catalog and optional
    // action interceptor (implementing A2uiActionInterceptor).
    private val processor = A2uiMessageProcessor(
        // You can also use the provided Material catalog instead of
        // a custom one.
        catalogs = listOf(CustomDesignSystemCatalog)
    )

    // Expose active surfaces to the UI as a StateFlow.
    val a2uiSurfaces: StateFlow<List<A2uiSurfaceModel>> =
        processor.activeSurfaces

    init {
        // Collect messages on a background thread tied to the ViewModel lifecycle.
        viewModelScope.launch(Dispatchers.Default) {
            processor.collectMessages()
        }

        // Add support for two-way communication with the agent.
        viewModelScope.launch(start = CoroutineStart.UNDISPATCHED) {
            processor.outboundEvents.collect(::handleOutboundA2uiEvent)
        }
    }

    // Called by your app's networking layer or business logic whenever
    // a new A2UI protocol message arrives from the AI agent.
    fun onNetworkMessage(json: String) {
        processor.processInput(parser, json)
    }
}

बेसिक कैटलॉग (Material 3) का इस्तेमाल करके, सर्फ़ेस रेंडर करना

दिए गए बेसिक कैटलॉग को लागू करने वाले टूल (androidx.compose.material3:material3-a2ui) का इस्तेमाल करके, रेंडरिंग की सुविधा देने वाले प्लैटफ़ॉर्म को रेंडर किया जा सकता है. साथ ही, पूरी तरह से स्टाइल किए गए Material 3 प्लैटफ़ॉर्म को रेंडर किया जा सकता है. इसमें लोडिंग इंडिकेटर, गड़बड़ी की सीमाएं, और ऐनिमेटेड ट्रांज़िशन के लिए पहले से मौजूद सहायता शामिल है. इसके लिए, A2uiSurface कंपोज़ेबल एंट्री पॉइंट का इस्तेमाल करें:

@Composable
fun AgenticUiScreen(viewModel: AgenticUiViewModel) {
    // Observe active surfaces managed by the data layer.
    val surfaces by viewModel.a2uiSurfaces.collectAsStateWithLifecycle()

    Column(Modifier.fillMaxSize()) {
        surfaces.forEach { surface ->
            key(surface.id) {
                A2uiSurface(
                    surfaceModel = surface,
                    // Add your surface's custom modifiers here.
                )
            }
        }
    }
}

सरफ़ेस की स्थितियों और ऐनिमेटेड ट्रांज़िशन को मैनेज करना

A2uiSurface, रूट कॉम्पोनेंट की स्थिति को हल करने में मदद करता है. साथ ही, लोड होने, गड़बड़ी होने, और पूरा होने की स्थितियों में AnimatedContent ट्रांज़िशन लागू करता है:

@Composable
fun CustomStyledSurface(surface: A2uiSurfaceModel) {
    A2uiSurface(
        surfaceModel = surface,
        modifier = Modifier.fillMaxSize(),
        loadingContent = {
            Box(Modifier.fillMaxSize(), contentAlignment = Alignment.Center) {
                CircularProgressIndicator()
            }
        },
        errorContent = { exception ->
            Text(
                text = "Failed to load: ${exception.message}",
                color = MaterialTheme.colorScheme.error,
                // Add your custom error styling, such as modifiers, here.
            )
        },
        transitionSpec = {
            (fadeIn(animationSpec = tween(600)) togetherWith
                    fadeOut(animationSpec = tween(600)))
                .using(SizeTransform(clip = false))
        },
    )
}

कस्टम राऊटर की मदद से, लो-लेवल पर सर्फ़ेस रेंडरिंग

observeA2uiComponentState की मदद से, सीधे तौर पर सर्फ़ेस रूट कॉम्पोनेंट की स्थिति देखी जा सकती है. साथ ही, रेंडरिंग को A2uiComponent को सौंपा जा सकता है:

@Composable
fun RawSurfaceCoordinator(surface: A2uiSurfaceModel) {
    // Extract the catalog to provide its readiness evaluator to the
    // composition. This lets components wait for their dynamic data bindings
    // before they're rendered.
    val coreSurface = surface as? A2uiCoreSurfaceModel
        ?: throw IllegalArgumentException(
            "Surface must implement A2uiCoreSurfaceModel")
    val composeCatalog = coreSurface.catalog as? A2uiCatalog
        ?: throw IllegalArgumentException("Catalog must implement A2uiCatalog")
    val readinessEvaluator = remember(composeCatalog) {
        composeCatalog.asReadinessEvaluator() }

    CompositionLocalProvider(
        LocalA2uiReadinessEvaluator provides readinessEvaluator
    ) {
        val rootState = observeA2uiComponentState(surface = surface)
        when (rootState) {
            is A2uiComponentState.Loading -> {
                LoadingSpinner()
            }
            is A2uiComponentState.Error -> {
                ErrorBanner(rootState.exception)
            }
            is A2uiComponentState.Success -> {
                // Delegate component routing to the Compose A2UI router.
                A2uiComponent(
                    component = rootState.component,
                    // Add your custom modifiers here.
                )
            }
        }
    }
}

लागू करने से जुड़ी जानकारी

एजेंट-टू-यूआई रेंडरर, सर्फ़ेस की स्थिति और गड़बड़ी से बचाव के लिए सीमाएं तय करता है.

गड़बड़ी की संभावना को कम करने के लिए, सीमाएं तय करना और एजेंट के गलत जवाब देने की समस्या को ठीक करना

A2UI की सतहें, जनरेटिव एलएलएम एजेंट की मदद से काम करती हैं. इसलिए, आने वाले पेलोड गलत फ़ॉर्मैट में हो सकते हैं या उनमें कॉम्पोनेंट के ऐसे टाइप का रेफ़रंस हो सकता है जिनके बारे में जानकारी नहीं है.

रेंडरर, क्रैश होने की आशंका को कम करने के लिए, सुरक्षा से जुड़ी इन सीमाओं को तय करता है:

  • एजेंट को गड़बड़ी की जानकारी देना, ताकि वह उसे ठीक कर सके: गड़बड़ियों की जानकारी, क्लाइंट को भेजे जाने वाले मैसेज के तौर पर दी जाती है. इससे एजेंट को बातचीत के अगले चरणों में गड़बड़ी ठीक करने में मदद मिलती है. एक ऐसा एपीआई भी है जो कॉम्पोनेंट लागू करने की सुविधा देता है. इसकी मदद से, एपीआई, एजेंट को गड़बड़ियों की सूचना भेज सकता है. ऐसा तब होता है, जब एपीआई को रेंडर करने के समय कॉम्पोनेंट से जुड़ी गड़बड़ियों का पता चलता है.
  • पहचान नहीं किए जा सकने वाले कॉम्पोनेंट: जब किसी ऐसे कॉम्पोनेंट टाइप का पता चलता है जिसकी पहचान नहीं की जा सकती, तो उसे यूज़र इंटरफ़ेस (यूआई) ट्री तक पहुंचने से पहले ही रोक दिया जाता है. साथ ही, उसे गड़बड़ी की स्थिति के तौर पर मार्क कर दिया जाता है. इसके बाद, एजेंट को इसकी सूचना दी जाती है, ताकि वह खुद ही इसे ठीक कर सके.
  • स्कीमा की पुष्टि नहीं हो पाई: पेलोड की पुष्टि, कॉम्पोनेंट स्कीमा (A2uiSchema) के हिसाब से की जाती है. गलत तरीके से बनाई गई प्रॉपर्टी, Compose यूज़र इंटरफ़ेस लेआउट तक नहीं पहुंचनी चाहिए.
  • स्पार्स-ऐरे सुरक्षा: जब बहुत बड़ी सूची के इंडेक्स मिलते हैं, तो डेटा मॉडल डेंस लिस्ट से अडैप्टिव स्पार्स मैप में बदल जाता है. इससे मेमोरी से जुड़ी गड़बड़ियां नहीं होती हैं.