Angular AI
The AIStreamService injectable connects Angular components to the AI streaming WebSocket using Angular signals. Import from @absolutejs/ai/angular.
#AIStreamService
Inject AIStreamService and call connect() with the WebSocket path. It returns an object with Angular computed signals for messages, streaming state, and errors. The service is provided in root and manages connection lifecycle : calling connect() with the same path reuses the existing connection.
TS
import { Component, OnInit } from '@angular/core';
import { AIStreamService } from '@absolutejs/ai/angular';
@Component({
selector: 'app-chat',
template: `
@for (msg of messages(); track msg.id) {
<div>
<strong>{{ msg.role }}:</strong> {{ msg.content }}
@if (msg.thinking) {
<details>
<summary>Thinking</summary>
<p>{{ msg.thinking }}</p>
</details>
}
</div>
}
@if (streaming()) {
<button (click)="cancel()">Stop</button>
}
@if (err()) {
<p style="color: red">{{ err() }}</p>
}
`,
})
export class ChatComponent implements OnInit {
private ai!: ReturnType<AIStreamService['connect']>;
messages = () => this.ai?.messages() ?? [];
streaming = () => this.ai?.isStreaming() ?? false;
err = () => this.ai?.error() ?? null;
constructor(private aiService: AIStreamService) {}
ngOnInit() {
this.ai = this.aiService.connect('/chat');
}
send(text: string) {
this.ai.send(text);
}
cancel() {
this.ai.cancel();
}
}#Return Type
TS
// AIStreamService.connect() return type (uses Angular signals)
{
send: (content: string, attachments?: AIAttachment[]) => void;
cancel: () => void;
branch: (messageId: string, content: string) => void;
messages: Signal<AIMessage[]>; // Angular computed signal
isStreaming: Signal<boolean>; // Angular computed signal
error: Signal<string | null>; // Angular computed signal
}