Factory function that creates a ContentClassifier โ a stateful, per-message service that detects content type from the token stream and routes to the appropriate parser.
Import:
import { createContentClassifier } from '@ngaf/chat';import type { ContentClassifier, ContentType } from '@ngaf/chat';
Signature
function createContentClassifier(): ContentClassifier
Returns:ContentClassifier โ a stateful classifier instance. Must be called within an Angular injection context (signals require it).
ContentClassifier Interface
interface ContentClassifier { /** Feed the full message content snapshot. Internally computes delta. */ update(content: string): void; /** Detected content type. */ readonly type: Signal<ContentType>; /** Accumulated markdown prose. Empty for pure JSON messages. */ readonly markdown: Signal<string>; /** Materialized JSON-render spec. Null until JSON is detected. */ readonly spec: Signal<Spec | null>; /** Per-element accumulation tracking. */ readonly elementStates: Signal<Map<string, ElementAccumulationState>>; /** True while content is still arriving. */ readonly streaming: Signal<boolean>; /** A2UI surfaces parsed from the stream. */ readonly a2uiSurfaces: Signal<Map<string, A2uiSurface>>; /** Parse errors encountered (non-fatal). */ readonly errors: Signal<string[]>; /** Clean up resources. */ dispose(): void;}
A2UI payload detected via ---a2ui_JSON--- prefix, parsed as JSONL messages
mixed
Markdown followed by structured content
a2uiSurfaces
When the content type is a2ui, this signal contains all parsed A2UI surfaces with their components and data models. The map is keyed by surface ID and updates incrementally as JSONL lines arrive during streaming.
errors
Parse errors are captured but don't stop the classifier. Partial results continue to render. Useful for diagnostics โ check this signal when debugging unexpected rendering behavior or malformed agent output.
Usage
const classifier = createContentClassifier();// Feed full content snapshots โ delta is computed internallyclassifier.update('Hello world');classifier.type(); // 'markdown'classifier.markdown(); // 'Hello world'// For JSON contentconst jsonClassifier = createContentClassifier();jsonClassifier.update('{"root":"r1","elements":{}}');jsonClassifier.type(); // 'json-render'jsonClassifier.spec(); // { root: 'r1', elements: {} }// Always dispose when doneclassifier.dispose();
Delta processing
Pass the full message content each time, not just new characters. The classifier tracks processedLength internally and only processes the delta.