provideStream and provideStreamDefaults wire LangGraph streaming through Angular's dependency injection. Child components read a shared stream with injectStream.
@langchain/angular exposes three DI primitives so a stream can be
shared across a subtree, configured globally, or wrapped in a
class-based service.
Set apiUrl (and optional client / apiKey) once in app.config.ts:
import { ApplicationConfig } from "@angular/core";
import { provideStreamDefaults } from "@langchain/angular";
export const appConfig: ApplicationConfig = {
providers: [
provideStreamDefaults({
apiUrl: "http://localhost:2024",
}),
],
};
Any injectStream call in the app inherits those defaults unless overridden per call.
Add provideStream to a parent component's providers array so descendants share one stream instance:
import { Component } from "@angular/core";
import { provideStream, injectStream } from "@langchain/angular";
@Component({
providers: [provideStream({ assistantId: "agent" })],
template: `
<app-message-list />
<app-message-input />
`,
})
export class ChatContainer {}
@Component({
template: `
@for (msg of stream.messages(); track msg.id) {
<div>{{ msg.content }}</div>
}
`,
})
export class MessageListComponent {
readonly stream = injectStream();
}
Companion selectors (injectMessages, injectToolCalls, etc.) take the stream handle from injectStream():
import { Component, inject } from "@angular/core";
import { injectStream, injectMessages } from "@langchain/angular";
@Component({
/* ... */
})
export class MessageListComponent {
private readonly stream = injectStream();
readonly messages = injectMessages(this.stream);
}
Pass the agent brand to injectStream to flow state / tool-call / subagent inference through:
import type { agent } from "./agent";
import { injectStream } from "@langchain/angular";
readonly stream = injectStream<typeof agent>();
See Type safety.
Provide separate provideStream({ assistantId: "…" }) entries on different parent components — each injector subtree gets its own stream handle.
StreamServiceStreamService is a thin @Injectable()
wrapper around the lower-level useStream factory. Extend it when you
want a providedIn: "root" or component-scoped service that forwards
the full StreamApi surface:
import { Injectable } from "@angular/core";
import { StreamService } from "@langchain/angular";
import type { BaseMessage } from "@langchain/core/messages";
interface ChatState {
messages: BaseMessage[];
}
@Injectable({ providedIn: "root" })
export class ChatStream extends StreamService<ChatState> {
constructor() {
super({
assistantId: "agent",
apiUrl: "http://localhost:2024",
});
}
}
Consumers inject(ChatStream) and read chat.messages(), call
chat.submit(...), etc. The service exposes the same surface as
injectStream; the raw StreamApi handle is also available as
chat.stream for code that needs to pass it into selector injectors.
provideStream accepts the same discriminated option bag as injectStream, including a custom AgentServerAdapter:
import { HttpAgentServerAdapter, provideStream } from "@langchain/angular";
const transport = new HttpAgentServerAdapter({
apiUrl: "/api/chat",
threadId: "thread-123",
});
@Component({
providers: [provideStream({ transport })],
/* ... */
})
export class ChatContainer {}
See Transports.
| Use case | Primitive |
|---|---|
| Share one stream across sibling components in a subtree | provideStream + zero-argument injectStream() |
Set app-wide apiUrl, apiKey, or client defaults |
provideStreamDefaults |
| Expose stream logic through a class-based service, add bespoke methods, or make unit mocking simple | StreamService |
| Own a controller outside an Angular injection context | useStream(options, destroyRef?) |