Introduction
@ngaf/chat is the Angular UI component library for building chat interfaces on top of a runtime-neutral Agent contract. It provides a complete set of composable, Signal-driven components that render messages, handle user input, display tool calls, manage interrupts, and support generative UI -- all styled with CSS custom properties and built for Angular 20+.
This guide explains the library's two-tier architecture, how it relates to the rest of the Cacheplane stack, and when to reach for the all-in-one composition versus assembling primitives yourself.
Two-Tier Architecture
The library is organized into two layers: primitives and compositions.
Primitives
Primitives are low-level, headless components that read from an Agent and expose their state through content projection (ng-template). They carry no opinion about layout or styling. Use them when you need full control over how chat elements render.
| Primitive | Selector | Purpose |
|---|---|---|
ChatMessagesComponent | chat-messages | Iterates messages and renders via template directives |
MessageTemplateDirective | ng-template[chatMessageTemplate] | Declares a template for a specific message type |
ChatInputComponent | chat-input | Text input with submit handling and keyboard shortcuts |
ChatTypingIndicatorComponent | chat-typing-indicator | Animated dots shown while the agent is streaming |
ChatErrorComponent | chat-error | Displays error messages from the agent |
ChatInterruptComponent | chat-interrupt | Projects interrupt content via a template |
ChatToolCallsComponent | chat-tool-calls | Iterates tool calls and projects each via a template |
ChatSubagentsComponent | chat-subagents | Iterates active subagent streams via a template |
ChatThreadListComponent | chat-thread-list | Renders a list of conversation threads |
ChatTimelineComponent | chat-timeline | Iterates checkpoint history via a template |
Compositions
Compositions are opinionated, styled components that combine primitives into ready-to-use UI blocks. They include CHAT_THEME_STYLES and CHAT_MARKDOWN_STYLES out of the box.
| Composition | Selector | Purpose |
|---|---|---|
ChatComponent | chat | Full chat UI with messages, input, typing indicator, error, and thread sidebar |
ChatInterruptPanelComponent | chat-interrupt-panel | Styled interrupt card with accept/edit/respond/ignore actions |
ChatToolCallCardComponent | chat-tool-call-card | Expandable card showing tool name, inputs, and output |
ChatSubagentCardComponent | chat-subagent-card | Expandable card showing subagent status and messages |
ChatDebugComponent | chat-debug | Full debug cockpit with timeline, state inspector, and diff viewer |
ChatTimelineSliderComponent | chat-timeline-slider | Slider-based timeline navigation |
How the Stack Fits Together
@ngaf/chat sits between your application and two other Cacheplane libraries:
-
@ngaf/langgraphprovides theagent()function and returns aLangGraphAgent, which satisfies theAgentcontract consumed by@ngaf/chat. It exposes reactive Signals formessages(),isLoading(),error(),interrupt(),toolCalls(),history(), and more. -
@ngaf/renderprovidesRenderSpecComponentand view registries for rendering JSON UI specs as Angular components. TheChatComponentauto-detects JSON specs in AI messages and renders them through@ngaf/render— pass a view registry via the[views]input. TheChatComponentalso auto-detects A2UI v0.9 payloads and renders them using a built-in 12-component catalog.
When to Use ChatComponent vs. Custom Assembly
Use ChatComponent when you want a complete, styled chat interface with minimal setup. It includes message rendering (with markdown), a text input, typing indicator, error display, interrupt banner, and an optional thread sidebar. Drop it in, pass an Agent, and you have a working chat.
Assemble primitives when you need to customize layout, add components between sections, change the message rendering logic, or integrate chat into a larger dashboard. Primitives give you building blocks without opinions.