From 90e12c33704a7f0ae77eb701ae13518f9add6592 Mon Sep 17 00:00:00 2001
From: Brian Love
-
-
+ The Last Mile Problem
+
+ The issue is not generating a demo. It is shipping a trustworthy product.
+
+ {s.label}
+
+ Your backend agent may already work. The frontend and production path is what slips the schedule.
+
+ The Complete Angular Agent Stack
+
+ LangGraph signals flow top to bottom through each layer — primitives to UI to generative components.
+
+ LangGraph Cloud
+
+ {layer.pkg}
+
+ Available now
+
+ Coming soon{' '}
+
+ Planned
+
+
+ On the horizon
+
+ Deploy api-service v2.1.0 to production? This will affect live traffic across all regions.
+
+ @cacheplane/chat
+
+ Click a feature to see the component in action.
+
+ {co.tag}
+ {co.body}
+ {co.tag}
+ {co.body}
+ A fair comparison
+
+ LangChain and LangGraph are excellent. This is what the Angular production layer provides on top.
+ The Angular Agent Readiness Guide
+ Free Download
+
+ The Angular Agent Readiness Guide. Six chapters. Six production-readiness dimensions.
+ What separates demos from shipped products.
+
+ Optional — Get notified of updates
+ Agent StreamResource Angular Agent Framework Angular Stream Resource
+
+
-
+
@@ -27,14 +27,14 @@
---
-`agent()` is the Angular equivalent of LangGraph's React `useStream()` hook — a full-parity implementation built on Angular Signals and the Angular Resource API. It gives enterprise Angular teams the same production-grade streaming primitives available to React developers on LangChain, without compromises or workarounds. Drop it into any Angular 20+ component, point it at your LangGraph Platform endpoint, and get reactive, signal-driven access to streaming state, messages, tool calls, interrupts, and thread history.
+`streamResource()` is the Angular equivalent of LangGraph's React `useStream()` hook — a full-parity implementation built on Angular Signals and the Angular Resource API. It gives enterprise Angular teams the same production-grade streaming primitives available to React developers on LangChain, without compromises or workarounds. Drop it into any Angular 20+ component, point it at your LangGraph Platform endpoint, and get reactive, signal-driven access to streaming state, messages, tool calls, interrupts, and thread history.
---
## Install
```bash
-npm install @cacheplane/angular
+npm install @cacheplane/stream-resource
```
**Peer dependencies:** `@angular/core ^20.0.0 || ^21.0.0`, `@langchain/core ^1.1.0`, `@langchain/langgraph-sdk ^1.7.0`, `rxjs ~7.8.0`
@@ -45,7 +45,7 @@ npm install @cacheplane/angular
```typescript
import { Component } from '@angular/core';
-import { agent } from '@cacheplane/angular';
+import { streamResource } from '@cacheplane/stream-resource';
import type { BaseMessage } from '@langchain/core/messages';
@Component({
@@ -65,7 +65,7 @@ import type { BaseMessage } from '@langchain/core/messages';
`,
})
export class ChatComponent {
- chat = agent<{ messages: BaseMessage[] }>({
+ chat = streamResource<{ messages: BaseMessage[] }>({
apiUrl: 'https://your-langgraph-platform.com',
assistantId: 'my-agent',
messagesKey: 'messages',
@@ -83,7 +83,7 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp
## Feature Comparison
-| Feature | `agent()` (Angular) | `useStream()` (React) |
+| Feature | `streamResource()` (Angular) | `useStream()` (React) |
|---|---|---|
| Streaming state as reactive primitives | Angular Signals | React state |
| Messages signal | `messages()` | `messages` |
@@ -99,7 +99,7 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp
| Submit | `submit(values, opts?)` | `submit(values, opts?)` |
| Stop | `stop()` | `stop()` |
| Reload last submission | `reload()` | — |
-| Custom transport (for testing) | `MockAgentTransport` | mock fetch |
+| Custom transport (for testing) | `MockStreamTransport` | mock fetch |
| Angular `ResourceRef
+ Most AI projects get close.
+
+ Almost none ship.
+
+ Three packages. One architecture.
+
+ Nothing left to wire yourself.
+
+ Every agent UI primitive,
+
+ ready to compose.
+
+ What StreamResource adds
+
+
')
+ .replace(/^### (.+)$/gm, '$1$1
')
+ .replace(/^## (.+)$/gm, '$1
')
+ .replace(/\*\*(.+?)\*\*/g, '$1')
+ .replace(/^- (.+)$/gm, '${match}
`)
+ .split('\n\n')
+ .map(block => {
+ if (block.startsWith('${ch.title}
+ From Prototype
+
to ProductionContents
+ ${tocHTML}
+
+ From Prototype
+
to Production
+