|
1 | | -Angular implementation of A2UI. |
| 1 | +# A2UI Angular Renderer |
2 | 2 |
|
3 | | -Important: The sample code provided is for demonstration purposes and illustrates the mechanics of A2UI and the Agent-to-Agent (A2A) protocol. When building production applications, it is critical to treat any agent operating outside of your direct control as a potentially untrusted entity. |
| 3 | +The `@a2ui/angular` package provides the Angular implementation for rendering A2UI surfaces, bridging the Agent-to-Agent (A2A) protocol to Angular-friendly components. |
| 4 | + |
| 5 | +## Architecture & Versions |
| 6 | + |
| 7 | +The package contains evolving architectures to support different A2UI specification versions: |
| 8 | + |
| 9 | +- **`v0_8`**: Initial approach utilizing dedicated, static Angular components for each element type (e.g., `<a2ui-button>`). |
| 10 | +- **`v0_9`**: Dynamic approach centering around a single generic host component (`ComponentHostComponent`) coupled with extensible `Catalog` registries. **This is the recommended architecture for modern integrations.** |
| 11 | + |
| 12 | +--- |
| 13 | + |
| 14 | +## Getting Started (`v0_9`) |
| 15 | + |
| 16 | +The `v0_9` model decouples rendering mechanics from static templates by binding model state dynamically through dynamic component allocation. |
| 17 | + |
| 18 | +### 1. Register Components in a Catalog |
| 19 | + |
| 20 | +Extend `AngularCatalog` or use preset catalogs like `MinimalCatalog`. Define your custom elements using a dynamic mapping: |
| 21 | + |
| 22 | +```typescript |
| 23 | +import { Injectable } from '@angular/core'; |
| 24 | +import { MinimalCatalog } from '@a2ui/angular/lib/v0_9/catalog/minimal/minimal-catalog'; |
| 25 | +import { CustomComponent } from './custom-component'; |
| 26 | + |
| 27 | +@Injectable({ providedIn: 'root' }) |
| 28 | +export class MyCatalog extends MinimalCatalog { |
| 29 | + constructor() { |
| 30 | + super(); |
| 31 | + |
| 32 | + const customApi = { |
| 33 | + name: 'CustomComponent', |
| 34 | + schema: { ... }, // Zod schema spec |
| 35 | + component: CustomComponent, |
| 36 | + }; |
| 37 | + |
| 38 | + const components = Array.from(this.components.values()); |
| 39 | + components.push(customApi); |
| 40 | + |
| 41 | + // Merge custom registrations |
| 42 | + (this as any).components = new Map(components.map((c) => [c.name, c])); |
| 43 | + } |
| 44 | +} |
| 45 | +``` |
| 46 | + |
| 47 | +### 2. Provide Renderer Infrastructure |
| 48 | + |
| 49 | +In your dashboard component or module providers tier, initialize the `A2uiRendererService` and declare the backing `AngularCatalog`: |
| 50 | + |
| 51 | +```typescript |
| 52 | +import { Component, inject, OnInit } from '@angular/core'; |
| 53 | +import { A2uiRendererService } from '@a2ui/angular/lib/v0_9/core/a2ui-renderer.service'; |
| 54 | +import { AngularCatalog } from '@a2ui/angular/lib/v0_9/catalog/types'; |
| 55 | +import { MyCatalog } from './my-catalog'; |
| 56 | + |
| 57 | +@Component({ |
| 58 | + selector: 'app-dashboard', |
| 59 | + providers: [ |
| 60 | + A2uiRendererService, |
| 61 | + { provide: AngularCatalog, useClass: MyCatalog }, |
| 62 | + ] |
| 63 | +}) |
| 64 | +``` |
| 65 | + |
| 66 | +### 3. Initialize Layout and Render |
| 67 | + |
| 68 | +Prepare the service on load and supply the generic host targeting the source surface: |
| 69 | + |
| 70 | +```typescript |
| 71 | +export class DashboardComponent implements OnInit { |
| 72 | + private rendererService = inject(A2uiRendererService); |
| 73 | + surfaceId = 'dashboard-surface'; |
| 74 | + |
| 75 | + ngOnInit() { |
| 76 | + this.rendererService.initialize(); |
| 77 | + } |
| 78 | + |
| 79 | + onMessagesReceived(messages: any[]) { |
| 80 | + this.rendererService.processMessages(messages); |
| 81 | + } |
| 82 | +} |
| 83 | +``` |
| 84 | + |
| 85 | +Place the `<a2ui-v09-component-host>` component in your template pointing to the desired layout node: |
| 86 | + |
| 87 | +```html |
| 88 | +<a2ui-v09-component-host [surfaceId]="surfaceId" componentId="root"> |
| 89 | +</a2ui-v09-component-host> |
| 90 | +``` |
| 91 | + |
| 92 | +--- |
| 93 | + |
| 94 | +## Building and Development |
| 95 | + |
| 96 | +### Building the Package |
| 97 | +Distributes the library bundle utilizing `ng-packagr` outputting to `./dist`: |
| 98 | +```bash |
| 99 | +npm run build |
| 100 | +``` |
| 101 | + |
| 102 | +### Running the Demo |
| 103 | +Starts a dev environment rendering local samples containing live inspectors reviewing data pipelines: |
| 104 | +```bash |
| 105 | +npm run demo |
| 106 | +``` |
| 107 | + |
| 108 | +--- |
| 109 | + |
| 110 | +## Legal Notice |
| 111 | + |
| 112 | +**Important**: The sample code provided is for demonstration purposes and illustrates the mechanics of A2UI and the Agent-to-Agent (A2A) protocol. When building production applications, it is critical to treat any agent operating outside of your direct control as a potentially untrusted entity. |
4 | 113 |
|
5 | 114 | All operational data received from an external agent—including its AgentCard, messages, artifacts, and task statuses—should be handled as untrusted input. For example, a malicious agent could provide crafted data in its fields (e.g., name, skills.description) that, if used without sanitization to construct prompts for a Large Language Model (LLM), could expose your application to prompt injection attacks. |
6 | 115 |
|
7 | 116 | Similarly, any UI definition or data stream received must be treated as untrusted. Malicious agents could attempt to spoof legitimate interfaces to deceive users (phishing), inject malicious scripts via property values (XSS), or generate excessive layout complexity to degrade client performance (DoS). If your application supports optional embedded content (such as iframes or web views), additional care must be taken to prevent exposure to malicious external sites. |
8 | 117 |
|
9 | | -Developer Responsibility: Failure to properly validate data and strictly sandbox rendered content can introduce severe vulnerabilities. Developers are responsible for implementing appropriate security measures—such as input sanitization, Content Security Policies (CSP), strict isolation for optional embedded content, and secure credential handling—to protect their systems and users. |
| 118 | +**Developer Responsibility**: Failure to properly validate data and strictly sandbox rendered content can introduce severe vulnerabilities. Developers are responsible for implementing appropriate security measures—such as input sanitization, Content Security Policies (CSP), strict isolation for optional embedded content, and secure credential handling—to protect their systems and users. |
0 commit comments