Komponentenkataloge erstellen und anpassen

In der A2UI-Architektur wird jede Oberfläche von einem Komponentenkatalog gesteuert. Ein Katalog ist ein formaler Vertrag, in dem die UI-Komponenten, Eigenschaftsschemas und lokalen Clientfunktionen definiert sind, die einem KI-Agenten zur Verfügung stehen. Anstatt beliebigen Code zu generieren oder unbekannte Elemente zu erfinden, muss der Agent Benutzeroberflächen ausschließlich mit den im Katalog deklarierten Komponenten erstellen.

Mit anderen Worten: Im Katalog werden die Komponenten deklariert und der Agent verwendet sie, um die Benutzeroberfläche Ihrer App zu erstellen.

Wenn Sie eine Android-App mit dem Jetpack Compose A2UI-Renderer erstellen, haben Sie flexible Optionen für die Bereitstellung von Katalogen:

  • Der Basic Catalog: Im A2UI-Projekt wird eine standardisierte Spezifikation Basic Catalog für allgemeine Zwecke definiert, die gängige Elemente wie Schaltflächen, Text, Textfelder, Karten und Listen enthält. Die AndroidX-Bibliothek androidx.compose.material3:material3-a2ui bietet eine sofort einsatzbereite Implementierung dieser Basic Catalog-Spezifikation mit nativen Material Design 3-Komponenten. Die androidx.a2ui.compose:compose-ui-Bibliothek enthält auch eine generische Schemadefinition für den Basic Catalog, mit der Sie den Basic Catalog für Ihr eigenes Designsystem implementieren können.
  • Benutzerdefinierte Kataloge: Für Produktionsanwendungen mit eigenen Designsystemen können Sie einen benutzerdefinierten Katalog von Grund auf neu erstellen. Dadurch wird der Agent auf die genauen Komponenten, Styling-Tokens und die visuelle Sprache Ihrer App beschränkt.
  • Teilmengen oder Hybridlösungen: Sie können bestimmte Komponentenimplementierungen aus dem bereitgestellten Basiskatalog mit Ihren eigenen benutzerdefinierten Komponenten kombinieren oder einzelne Komponentenimplementierungen in der Basiskatalog-Suite überschreiben.

Den bereitgestellten Basic Catalog verwenden

Wenn Sie schnell loslegen möchten, ohne ein Komponentenschema von Grund auf neu zu erstellen, können Sie die bereitgestellte Implementierung der A2UI Basic Catalog-Spezifikation verwenden. Die androidx.compose.material3:material3-a2ui-Bibliothek implementiert den Basic Catalog mit Material Design 3-Komponenten.

Wenn Sie materialA2uiBasicCatalogV1 instanziieren, müssen Sie Renderer und Handler für Folgendes angeben:

  • Medienkomponenten wie Bilder, Video- und Audioplayer
  • URL-Öffner
  • Lokalisierte Nachrichtenformatierung

Die A2UI-Bibliotheken enthalten absichtlich keine externen Media- und Netzwerkabhängigkeiten wie Coil, Glide oder Media3. Stattdessen stellen Sie Ihre eigenen Renderer bereit. Dadurch werden Abhängigkeitskonflikte vermieden, da eindeutige Bibliotheken bereitgestellt werden. Wenn Ihre App beispielsweise bereits Coil zum Laden von Bildern oder Media3 zur Wiedergabe verwendet, können Sie diese vorhandenen Bibliotheken direkt in den Katalog einbinden.

Das folgende Beispiel zeigt, wie Sie den einfachen Katalog instanziieren und Ihre bevorzugten Media-Bibliotheken, den URL-Öffner und den Nachrichtenformatierer einbinden:

// Instantiate the provided Basic Catalog (implemented with Material 3)
val basicCatalog = materialA2uiBasicCatalogV1(
    // Example: Wire up Coil for image loading (via AsyncImage)
    image = MaterialA2uiBasicCatalogV1Defaults.image {
            url, description, scale, modifier, onError ->
        AsyncImage(
            model = url,
            contentDescription = description,
            contentScale = scale,
            modifier = modifier,
            onError = { state -> onError(state.result.throwable) },
        )
    },

    // Example: Use ExoPlayer/Media3 for video
    video = MaterialA2uiBasicCatalogV1Defaults.video { url, modifier, onError ->
        // Custom ExoPlayer video integration here
    },

    // Example: Use an audio player
    audioPlayer = MaterialA2uiBasicCatalogV1Defaults.audioPlayer {
            url, description, modifier, onError ->
        // Custom audio integration here
    },

    // Handle outbound URLs, such as using an app navigator or context intents.
    urlOpener = { url ->
        appNavigator.openUrl(url)
    },

    // Handle localized message formatting
    messageFormatter = { pattern, locale, args ->
        MessageFormat.format(context, locale, pattern, args)
    },
    localeProvider = A2uiLocaleProvider.Default,
)

Benutzerdefinierten Komponenten-Katalog von Grund auf neu erstellen

Wenn Ihre App ein benutzerdefiniertes Designsystem verwendet, können Sie einen eigenen Katalog mit Ihren eigenen benutzerdefinierten A2uiComponent-Implementierungen definieren. Mit diesem Ansatz haben Sie die vollständige Kontrolle über die Komponentenschemas, die für den Agenten verfügbar sind, und die ausgegebene native Compose-Benutzeroberfläche:

// Define a custom catalog that mirrors your app's design system
val CustomDesignSystemCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-design-system/v1/catalog.json",
    components = listOf(
        CustomButtonComponent,
        CustomCardComponent,
        CustomTextFieldComponent,
    ),
    functions = listOf(MyCustomLocalFunction()),
)

Eine Anleitung zum Definieren einzelner Komponentenschemas und ihrer Compose-UI-Rendering-Logik finden Sie unter Benutzerdefinierte A2UI-Komponenten implementieren.

Teilmengen von Basic Catalog-Komponenten mit benutzerdefinierten Komponenten verwenden

Sie müssen sich nicht zwischen einer kompletten Neuentwicklung und der Übernahme des gesamten Basiskatalogs entscheiden. Sie können einen Katalog zusammenstellen, in dem ausgewählte Komponenten aus der bereitgestellten Implementierung des Basiskatalogs mit Ihren eigenen benutzerdefinierten Komponenten kombiniert werden:

// Assemble a catalog using select Basic Catalog components alongside custom components
val hybridCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v1/catalog.json",
    components = listOf(
        // Use provided Basic Catalog components (built with Material 3)
        MaterialA2uiBasicCatalogV1Defaults.text,
        MaterialA2uiBasicCatalogV1Defaults.card,

        // Add proprietary components from your app's design system
        CustomChartComponent,
        CustomProductCardComponent,
    ),
    functions = createBasicCatalogFunctions(...),
)

Alternativ können Sie die bereitgestellte Basic Catalog-Suite anpassen, indem Sie bestimmte Komponentenslots überschreiben:

// Override specific components within the Basic Catalog suite
val customizedBasicCatalog = materialA2uiBasicCatalogV1(
    // Supply required renderers (such as Coil or ExoPlayer) as shown earlier
    image = MaterialA2uiBasicCatalogV1Defaults.image(myImageRenderer),
    video = MaterialA2uiBasicCatalogV1Defaults.video(myVideoRenderer),
    audioPlayer = MaterialA2uiBasicCatalogV1Defaults
        .audioPlayer(myAudioRenderer),
    urlOpener = { url -> /* Open URL */ },
    messageFormatter = { pattern, _, _ -> pattern },
    localeProvider = A2uiLocaleProvider.Default,
    // Replaces the default button. If you use this, implement the
    // A2uiBasicCatalogV1.Button interface.
    button = MyCustomBrandButtonComponent,
    
)

Katalogversionierung und Schemaentwicklung verwalten

A2UI-Kataloge werden explizit anhand ihres JSON-Schemavertrags versioniert. Eine Versionserhöhung ist erforderlich, wenn grundlegende Schemaänderungen eingeführt werden:

// Original component (v1 catalog)
object CustomButtonComponent : A2uiComponent { ... }

// Unchanged component across versions
object CustomTextComponent : A2uiComponent { ... }

// Future breaking schema change (v2 catalog)
object CustomButtonComponentV2 : A2uiComponent { ... }

// Assembles the v1 catalog
fun customCatalogV1(
    button: A2uiComponent = CustomButtonComponent,
    text: A2uiComponent = CustomTextComponent,
): A2uiCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v1/catalog.json",
    components = listOf(button, text),
)

// Assembles the v2 catalog
fun customCatalogV2(
    button: A2uiComponent = CustomButtonComponentV2,
    text: A2uiComponent = CustomTextComponent,
): A2uiCatalog = A2uiCatalog(
    catalogId = "https://example.com/catalogs/my-app/v2/catalog.json",
    components = listOf(button, text),
)

Damit Migrationen ohne Ausfallzeiten möglich sind, kann Ihr Client mehrere unterstützte Katalogversionen gleichzeitig beim Message-Prozessor registrieren:

private val processor = A2uiMessageProcessor(
    catalogs = listOf(
        customCatalogV1(),
        customCatalogV2(),
    ),
)

Während der Katalogverhandlung ermittelt der Agent alle unterstützten Katalog-IDs und richtet sich für jede Oberfläche an der entsprechenden Version aus.

Details zur Implementierung

In den folgenden Abschnitten werden die interne Katalogvalidierung und die Schemavereinbarung erläutert.

In den Prozessen zur Katalogverwaltung werden die folgenden wichtigen APIs vorgestellt:

  • A2uiCatalog: Schnittstelle und Factory-Funktion der obersten Ebene zum Definieren von Komponentenkatalogen.
  • materialA2uiBasicCatalogVX: Versionierte Factory-Funktionen (z. B. materialA2uiBasicCatalogV1), die die Material 3-Implementierung der Standard-A2UI-Basiskatalog-Spezifikation bereitstellen.
  • A2uiReadinessEvaluator und asReadinessEvaluator(): A2uiReadinessEvaluator ist die Schnittstelle zum Bewerten der Einsatzbereitschaft von Komponenten. Die Erweiterungsfunktion asReadinessEvaluator() löst Bereitschaftsstatus mithilfe der in einem Katalog registrierten Komponenten auf.

A2UI-Versionskatalog und Komponentenschemas

Eine Katalogschemadefinition ist einer bestimmten Protokollversion zugeordnet. Wenn sich das Protokoll weiterentwickelt, wird die Version der Katalogdefinition aktualisiert. Komponentenimplementierungen für diese nächste Version können aktualisierte Renderer-APIs verwenden, während niedrigere Versionen parallel weiter funktionieren.