Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion LICENSE-COMMERCIAL
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,5 @@ Deschutes County, United States, without regard to conflict of law principles.
--- PURCHASING ---

To purchase a license or inquire about Enterprise terms:
Website: https://stream-resource.dev/pricing
Website: https://cacheplane.ai/pricing
Email: hello@cacheplane.ai
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<p align="center">
<img
src="https://cacheplane.ai/assets/hero.svg"
alt="Angular Agent Framework — The Enterprise Streaming Resource for LangChain and Angular"
alt="Angular Agent Framework — The Angular Agent Framework for LangChain"
width="100%"
/>
</p>

<p align="center">
<em>The Enterprise Streaming Resource for LangChain and Angular</em>
<em>The Angular Agent Framework for LangChain</em>
</p>

<p align="center">
Expand All @@ -27,7 +27,7 @@

---

`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.
`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.

---

Expand All @@ -45,7 +45,7 @@ npm install @cacheplane/angular

```typescript
import { Component } from '@angular/core';
import { streamResource } from '@cacheplane/angular';
import { agent } from '@cacheplane/angular';
import type { BaseMessage } from '@langchain/core/messages';

@Component({
Expand All @@ -65,7 +65,7 @@ import type { BaseMessage } from '@langchain/core/messages';
`,
})
export class ChatComponent {
chat = streamResource<{ messages: BaseMessage[] }>({
chat = agent<{ messages: BaseMessage[] }>({
apiUrl: 'https://your-langgraph-platform.com',
assistantId: 'my-agent',
messagesKey: 'messages',
Expand All @@ -83,7 +83,7 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp

## Feature Comparison

| Feature | `streamResource()` (Angular) | `useStream()` (React) |
| Feature | `agent()` (Angular) | `useStream()` (React) |
|---|---|---|
| Streaming state as reactive primitives | Angular Signals | React state |
| Messages signal | `messages()` | `messages` |
Expand Down Expand Up @@ -111,12 +111,12 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp
<p align="center">
<img
src="https://cacheplane.ai/assets/arch-diagram.svg"
alt="Angular Agent Framework architecture: Angular Component → streamResource() → StreamManager Bridge → LangGraph Platform, with signals returned reactively"
alt="Angular Agent Framework architecture: Angular Component → agent() → StreamManager Bridge → LangGraph Platform, with signals returned reactively"
width="100%"
/>
</p>

`streamResource()` creates 12 `BehaviorSubject`s at injection-context time — once, at component construction. The `StreamManager` bridge (the only file that touches `@langchain/langgraph-sdk` internals) pushes stream events into those subjects. `toSignal()` converts each subject to an Angular Signal, also at construction time. Dynamic actions (`submit`, `stop`, `switchThread`) push into the existing subjects — no new subjects are ever created after construction. This architecture is required because `toSignal()` must be called in an injection context and cannot be called again later.
`agent()` creates 12 `BehaviorSubject`s at injection-context time — once, at component construction. The `StreamManager` bridge (the only file that touches `@langchain/langgraph-sdk` internals) pushes stream events into those subjects. `toSignal()` converts each subject to an Angular Signal, also at construction time. Dynamic actions (`submit`, `stop`, `switchThread`) push into the existing subjects — no new subjects are ever created after construction. This architecture is required because `toSignal()` must be called in an injection context and cannot be called again later.

---

Expand Down
2 changes: 1 addition & 1 deletion cockpit/chat/input/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ out of the box. Listen for the `send` event:
<Step title="Track loading state">

The input automatically disables while the stream is active. Access
loading state via the stream resource:
loading state via the agent ref:

```typescript
protected readonly isLoading = computed(() => this.stream.status() === 'streaming');
Expand Down
8 changes: 4 additions & 4 deletions cockpit/chat/interrupts/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ and render approval/rejection controls.
</Prompt>

<Steps>
<Step title="Configure the stream resource">
<Step title="Configure the agent ref">

Set up `streamResource()` which automatically detects interrupt states
Set up `agent()` which automatically detects interrupt states
from the LangGraph backend:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand All @@ -28,7 +28,7 @@ protected readonly stream = streamResource({
</Step>
<Step title="Detect interrupt state">

Check the stream status for interrupt events. The stream resource exposes
Check the stream status for interrupt events. The agent ref exposes
interrupt data when the graph pauses:

```typescript
Expand Down
4 changes: 2 additions & 2 deletions cockpit/chat/subagents/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ graph.add_node("analysis_agent", analysis_agent)
<Step title="Track subagent status">

Each subagent node emits status updates that the frontend tracks.
The stream resource automatically detects node transitions:
The agent ref automatically detects node transitions:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
4 changes: 2 additions & 2 deletions cockpit/chat/threads/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ switching between conversations.
<Steps>
<Step title="Configure thread support">

Thread management is built into `streamResource()`. Each thread gets
Thread management is built into `agent()`. Each thread gets
a unique ID that persists its conversation state:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
4 changes: 2 additions & 2 deletions cockpit/chat/timeline/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@ to navigate checkpoints and branch from previous conversation states.
<Steps>
<Step title="Enable history tracking">

History tracking is built into `streamResource()`. Each message exchange
History tracking is built into `agent()`. Each message exchange
creates a checkpoint automatically:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
2 changes: 1 addition & 1 deletion cockpit/chat/timeline/python/prompts/timeline.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Chat Timeline Assistant

You are an assistant that demonstrates conversation timeline and
checkpoint navigation using stream-resource.
checkpoint navigation using the Angular agent() ref.

Each message exchange creates a checkpoint in the conversation timeline.
Users can navigate backward and forward through these checkpoints using
Expand Down
4 changes: 2 additions & 2 deletions cockpit/chat/timeline/python/src/graph.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
Chat Timeline Graph

A standard conversational agent. Timeline and checkpoint navigation
is managed by stream-resource on the frontend side.
is managed by the agent() ref on the frontend side.
"""

from pathlib import Path
Expand All @@ -16,7 +16,7 @@
def build_timeline_graph():
"""
Constructs a standard conversational agent.
Timeline/history navigation is handled by the stream-resource frontend.
Timeline/history navigation is handled by the Angular agent() frontend.
"""
llm = ChatOpenAI(model="gpt-5-mini", streaming=True)

Expand Down
4 changes: 2 additions & 2 deletions cockpit/render/computed-functions/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,10 @@ const spec = {
</Step>
<Step title="Connect to the backend">

Use `streamResource()` to receive specs with computed props from the agent:
Use `agent()` to receive specs with computed props from the agent:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
4 changes: 2 additions & 2 deletions cockpit/render/element-rendering/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,10 +68,10 @@ Visibility conditions at any level control the entire subtree below.
</Step>
<Step title="Connect to the backend">

Use `streamResource()` to receive element specs from the agent:
Use `agent()` to receive element specs from the agent:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
4 changes: 2 additions & 2 deletions cockpit/render/repeat-loops/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,10 @@ store.update((draft) => {
</Step>
<Step title="Connect to the backend">

Use `streamResource()` to receive repeat specs from the agent:
Use `agent()` to receive repeat specs from the agent:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
4 changes: 2 additions & 2 deletions cockpit/render/spec-rendering/python/docs/guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ store.get('/name'); // Signal<string>
</Step>
<Step title="Connect to the LangGraph backend">

Use `streamResource()` to connect to the agent and display render specs
Use `agent()` to connect to the agent and display render specs
from the conversation:

```typescript
protected readonly stream = streamResource({
protected readonly stream = agent({
apiUrl: environment.langGraphApiUrl,
assistantId: environment.streamingAssistantId,
});
Expand Down
132 changes: 132 additions & 0 deletions docs/superpowers/plans/2026-04-09-library-consolidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
# Library Consolidation Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Remove the empty `@cacheplane/stream-resource` directory and update all stale references so the monorepo reflects 3 libraries (angular, render, chat).

**Architecture:** Delete empty dir, find-and-replace references in README, LICENSE-COMMERCIAL, and cockpit docs.

**Tech Stack:** Git, Markdown, Python docs

---

### Task 1: Delete Empty libs/stream-resource Directory

**Files:**
- Delete: `libs/stream-resource/` (contains only `node_modules/`)

- [ ] **Step 1: Remove the directory**

```bash
rm -rf libs/stream-resource
```

- [ ] **Step 2: Verify removal**

```bash
ls libs/ | grep stream-resource
```
Expected: no output

- [ ] **Step 3: Commit**

```bash
git add -A libs/stream-resource
git commit -m "chore: remove empty libs/stream-resource directory"
```

---

### Task 2: Update README.md

**Files:**
- Modify: `README.md`

Replace all `streamResource()` references with `agent()`. Update tagline from "Streaming Resource" to "Angular Agent Framework". Update the 30-Second Example, Feature Comparison table, and Architecture section to use `agent()`.

- [ ] **Step 1: Update hero alt text and tagline**

Old: `The Enterprise Streaming Resource for LangChain and Angular`
New: `The Angular Agent Framework for LangChain`

- [ ] **Step 2: Update 30-Second Example**

Replace `streamResource<{ messages: BaseMessage[] }>({...})` with `agent<{ messages: BaseMessage[] }>({...})`. Update import from `streamResource` to `agent`.

- [ ] **Step 3: Update Feature Comparison table**

Replace `streamResource() (Angular)` with `agent() (Angular)` in the header row.

- [ ] **Step 4: Update Architecture section**

Replace all `streamResource()` with `agent()` in the architecture description.

- [ ] **Step 5: Commit**

```bash
git add README.md
git commit -m "docs: update README to use agent() instead of streamResource()"
```

---

### Task 3: Update LICENSE-COMMERCIAL

**Files:**
- Modify: `LICENSE-COMMERCIAL`

- [ ] **Step 1: Update URL**

Replace `https://stream-resource.dev/pricing` with `https://cacheplane.ai/pricing`.

- [ ] **Step 2: Commit**

```bash
git add LICENSE-COMMERCIAL
git commit -m "docs: update LICENSE-COMMERCIAL URL to cacheplane.ai"
```

---

### Task 4: Update Cockpit Python Docs

**Files:**
- Modify: `cockpit/chat/timeline/python/src/graph.py`
- Modify: `cockpit/chat/timeline/python/prompts/timeline.md`
- Modify: `cockpit/chat/timeline/python/docs/guide.md`
- Modify: `cockpit/chat/threads/python/docs/guide.md`
- Modify: `cockpit/chat/subagents/python/docs/guide.md`
- Modify: `cockpit/chat/interrupts/python/docs/guide.md`
- Modify: `cockpit/chat/input/python/docs/guide.md`
- Modify: `cockpit/render/spec-rendering/python/docs/guide.md`
- Modify: `cockpit/render/repeat-loops/python/docs/guide.md`
- Modify: `cockpit/render/element-rendering/python/docs/guide.md`
- Modify: `cockpit/render/computed-functions/python/docs/guide.md`

- [ ] **Step 1: Update all cockpit references**

In code examples: `streamResource({` → `agent({`
In prose: "stream-resource" → "agent", "stream resource" → "agent", "The stream resource" → "The agent ref"

- [ ] **Step 2: Commit**

```bash
git add cockpit/
git commit -m "docs: update cockpit guides from streamResource to agent"
```

---

### Task 5: Flag SVG Assets

**Files:**
- Note: `apps/website/public/assets/hero.svg`
- Note: `apps/website/public/assets/arch-diagram.svg`

These contain embedded "streamResource" text. They are generated assets that need manual regeneration — not text-editable. Add a TODO comment or note for future regeneration.

- [ ] **Step 1: Verify SVG references**

Confirm these are the only SVG files with stale references.

- [ ] **Step 2: No code change needed** — flag in PR description for future regeneration.
Loading
Loading