AG-UI mit Angular umsetzen

  1. AG-UI verstehen: Der Standard für Agentic User Interfaces
  2. AG-UI in der Praxis: Das SDK für TypeScript
  3. AG-UI mit Angular umsetzen

Agents via AG-UI in Angular-Anwendungen nutzen

AG-UI definiert die Kommunikation zwischen Frontend und Agent, liefert für Angular-Anwendungen aber noch keine vollständig idiomatische Abstraktion. Wer AI-Agents in Angular integrieren will, braucht deshalb eine Hülle, die sich natürlich in Komponenten, Signals und Templates einfügt.

Genau hier setzt dieser Artikel an. Er zeigt, wie sich AG-UI mit einer schlanken Angular-spezifischen Abstraktion über dem SDK nutzen lässt, sodass Agenten, clientseitige Tools und Widgets sauber in eine Angular-Anwendung eingebunden werden können.

📂 Source Code (siehe Branch agentic)

AG-UI in Angular integrieren

Für die Integration in Angular stellt das besprochene AG-UI SDK eine gute Basis dar. Um einen komfortablen Einsatz ohne unnötigen Boilerplate-Code zu ermöglichen, ist jedoch eine weitere Abstraktionsschicht notwendig. Das beiliegende Demo-Projekt enthält solch eine Abstraktion im Ordner libs/ag-ui-client. Um Importe zu vereinfachen, findet sich in der tsconfig.json ein Path-Mapping @internal/ag-ui-client, das darauf verweist.

Der Dreh- und Angelpunkt dieser Implementierung ist eine agUiResource zur Kommunikation mit dem Agent. Außerdem bietet sie eine Komponente WidgetContainer, die vom Agent angeforderte Komponenten wie die eingangs gezeigte Flugkarte anzeigt. Das dahinterstehende API-Design ist hochgradig vom Framework Hashbrown inspiriert, das aus Sicht von Angular Entwickler:innen einen äußerst idiomatischen Umgang mit LLMs ermöglicht, derzeit jedoch noch keine AG-UI-Integration mitbringt.

Der vorliegende Artikel betrachtet diese Abstraktion als Blackbox, die früher oder später von einer Bibliothek bereitgestellt werden sollte. Der Quellcode kann gerne als Basis für eigene Vorhaben genutzt werden.

Durch den Einsatz von AG-UI ist das Angular-Beispiel unabhängig von serverseitigen Technologien und Modellen. Um eine möglichst einfache Ausführung zu ermöglichen, enthält die Demo-Anwendung einen Agent, der das äußerst komfortable und auf TypeScript basierende Agent-Framework Mastra nutzt. Da das AG-UI SDK für Mastra einen Adapter bereitstellt, lassen sich damit entwickelte Agents einfach über AG-UI anbinden.

Der Client wurde sowohl mit OpenAIs GPT 5 als auch mit Googles Gemini 3 getestet. Details für das Einrichten und Starten der Demo finden sich in der Readme.

Agents über agUiResource in Angular anbinden

Die von @internal/ag-ui-client bereitgestellte agUiResource implementiert Angulars Resource API und lässt sich somit ähnlich wie die bekannten httpResource oder rxResource nutzen:

import { agUiResource } from '@internal/ag-ui-client';

[...]

export class TicketingComponent {
  private readonly chat = agUiResource({
    url: 'http://localhost:3001/ag-ui/ticketingAgent',
    useServerMemory: true,
    tools: [
      findFlightsTool,
      getLoadedFlightsTool,
      toggleFlightSelectionTool,
      getCurrentBasketTool,
      displayFlightDetailTool,
      createShowComponentsTool([flightWidgetComponent]),
    ],
  });
}

Die Eigenschaften verweisen auf die URL des Agents. Mit useServerMemory gibt der Aufrufer an, ob der Agent den Chatverlauf speichert. Ist dem nicht so, muss der Client den gesamten Chatverlauf in jeden Aufruf wiederholen.

In der Auflistung tools registriert der Konsument sämtliche clientseitigen Tools, deren Aufruf der Agent anfordern darf. Ein besonderes Tool ist showComponents, das über eine Factory erzeugt wird. Diese Factory nimmt die Beschreibung möglicher Komponenten entgegen, die der Agent zur Beantwortung von Fragen einbinden kann. In unserem Fall steht lediglich eine Flugkarte (flightWidget) zur Verfügung.

NOTE

Agentic UI with Angular

Mehr zu diesem Thema in meinem eBook: Baue skalierbare Agentic UIs mit Angular – mit AG-UI, A2UI und MCP Apps, offen und ohne Vendor Lock-in.

Cover des eBooks Agentic UI with Angular

Mehr zum eBook →

Die einzelnen Tools lassen sich mit der Funktion defineAgUiTool beschreiben:

import { defineAgUiTool } from '@internal/ag-ui-client';
import { z } from 'zod';

[...]

export const findFlightsTool = defineAgUiTool({
  name: 'findFlights',
  description: `Searches for flights and redirects the user to the result`,
  schema: z.object({
    from: z.string().describe('airport of departure'),
    to: z.string().describe('airport of destination'),
  }),
  execute: async (args) => {
    const store = inject(FlightStore);
    const router = inject(Router);
    store.updateFilter(args.from, args.to);
    await router.navigate(['/ticketing/booking/flight-search']);
  },
});

Neben einem Namen, einer Beschreibung und Parameterdefinitionen, die auf Zod basieren, enthält die Tooldefinition auch eine execute-Methode. Fordert der Agent ein Tool an, führt die agUiResource diese Methode aus.

Das Parameter-Objekt args unterliegt jenem TypeScript-Typ, der aus dem Zod-Schema hervorgeht. In unserem Fall handelt es sich dabei um ein Objekt mit den Eigenschaften from und to. Die gezeigte Implementierung triggert eine Flugsuche, indem sie diese Suchkriterien an den FlightStore übergibt und navigiert den Benutzer danach auf die Ergebnisseite.

Tools, die Daten in Erfahrung bringen, zum Beispiel lokal vorliegende Zustände oder Antworten des Benutzers, können diese über den Rückgabewert ans Modell zurückmelden. Ein Beispiel dafür ist das getLoadedFlightsTool, das den Agent über jene Flüge informiert, die die Anwendung dem Benutzer gerade anzeigt:

export const getLoadedFlightsTool = defineAgUiTool({
  name: 'getLoadedFlights',
  description: `Returns the currently loaded/displayed flights`,
  execute: () => {
    const store = inject(FlightStore);
    return store.flightsValue().map(toFlightInfo);
  },
});

Die Definition von Komponenten erfolgt ähnlich, jedoch beschreibt das übergebene Schema hier die angebotenen Inputs:

import { defineAgUiComponent } from '@internal/ag-ui-client';
import { z } from 'zod';

export const flightWidgetComponent = defineAgUiComponent({
  name: 'flightWidget',
  description: `Displays a concrete flight as an interactive card.
Use it when referring to one or more specific flights.`,
  component: FlightWidget,
  schema: z.object({
    flight: flightSchema,
    status: z.enum(['booked', 'other']).describe('Status of the flight'),
  }),
});

Die Eigenschaft flight verweist in diesem Beispiel auf ein weiteres Zod-Schema:

const flightSchema = z.object({
  id: z.number().describe('The flight id'),
  from: z.string().describe('Departure city'),
  to: z.string().describe('Arrival city'),
  date: z.string().describe('Departure date in ISO format'),
  delay: z.number().describe('Delay in minutes'),
});

Um eine Anfrage an den Agent zu senden, nutzt der Client die Methode sendMessage:

this.chat.sendMessage({
  role: 'user',
  content: 'Did I book my flight to France?',
});

Nun muss der Client nur noch die vom Agent via AG-UI retournierten Antwortnachrichten im Chatverlauf anzeigen.

Chatverlauf in Angular-Templates präsentieren

Der gesamte Chatverlauf befindet sich im value der AgUiResource. Es handelt sich um ein Signal, das ein Array mit AgUiChatMessages enthält:

@for (message of chat.value(); track message.id) {
  @if (message.content) {
    <div>{{ message.content }}</div>
  }
  @for (widget of message.widgets; track widget.id) {
    <app-widget-container [widget]="widget" />
  }
  @for (toolCall of message.toolCalls; track toolCall.id) {
    <div>Tool Call: {{ toolCall.name }}</div>
  }
}

Die iterierten Nachrichten enthalten neben einer textuellen Antwort (content) auch eine Auflistung mit Komponenten (widgets) und Tools (toolCalls). Bei den Widgets handelt es sich um Komponenten, die für das Tool showComponents registriert und vom LLM ausgewählt wurden. Der von @internal/ag-ui-client angebotene WidgetContainer kann diese Widgets dynamisch erzeugen und mit den vom Agent beziehungsweise LLM übergebenen Eigenschaften zur Anzeige bringen.

Die Auflistung toolCalls informiert über die angeforderten Tools. Die Einträge können sich sowohl auf clientseitige als auch auf serverseitige Tools beziehen und werden hier aus Gründen der Transparenz ausgegeben. Um die Ausführung clientseitiger Tools müssen wir uns hingegen nicht kümmern, denn diese Aufgabe übernimmt die agUiResource ohne weiteres Zutun.

Die gestreamten AG-UI-Nachrichten lassen sich über die Developer Tools des Browsers nachvollziehen:

Gestreamte AG-UI-Nachrichten in den Developer Tools des Browsers

Diese Informationen machen zum einen das Protokoll greifbar und helfen zum anderen beim Troubleshooting.

Zusammenfassung

Mit einer schlanken Angular-Abstraktion wie agUiResource lässt sich AG-UI idiomatisch in Komponenten, Tools und Templates integrieren. Der Client beschreibt verfügbare Tools und Widgets, sendet Benutzeranfragen an den Agent und verarbeitet gestreamte Antworten direkt als Signal-basierten Chatverlauf.

Als dritter Teil der Serie zeigt dieser Artikel die praktische Angular-Integration auf Basis der in den vorherigen Teilen eingeführten Konzepte und des TypeScript-SDKs.

FAQ

Wie lässt sich AG-UI in Angular integrieren?

AG-UI lässt sich in Angular am besten über eine eigene Abstraktion integrieren, die die Kommunikation mit dem Agent kapselt und sich sauber in Komponenten, Signals und Templates einfügt. Im gezeigten Beispiel übernimmt diese Aufgabe agUiResource.

Was ist agUiResource?

agUiResource ist eine Angular-spezifische Hülle über dem AG-UI-SDK. Sie verbindet den Agent mit der Angular-Anwendung, führt clientseitige Tools aus und stellt den Chatverlauf samt Widgets und Tool Calls als Resource bereit.

Warum braucht Angular über dem SDK noch eine weitere Abstraktion?

Das AG-UI-SDK ist bewusst generisch und low-level gehalten. Eine Angular-spezifische Abstraktion reduziert Boilerplate, passt besser zur Resource API und erleichtert die Einbindung in Templates, Stores und Routing.

Wie gelangen Tools und Widgets in den Chatverlauf?

Der Client registriert verfügbare Tools und Komponenten vor dem Run beim Agent. Wenn der Agent später Tool Calls oder Widgets anfordert, verarbeitet agUiResource diese Informationen und stellt sie im Signal-basierten Chatverlauf für das Template bereit.

Agentic UI with Angular

Architecting Agentic AI with Open Standards

Integriere AI-Agents in Angular mit offenen Standards.

Mehr zum Buch