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
6 changes: 6 additions & 0 deletions .claude/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@
"runtimeExecutable": "/bin/bash",
"runtimeArgs": ["-c", "export PATH=/Users/blove/.nvm/versions/node/v22.14.0/bin:$PATH && npx nx serve cockpit --port 4201"],
"port": 4201
},
{
"name": "streaming",
"runtimeExecutable": "/bin/bash",
"runtimeArgs": ["-c", "export PATH=/Users/blove/.nvm/versions/node/v22.14.0/bin:$PATH && npx nx serve cockpit-langgraph-streaming-angular --port 4300"],
"port": 4300
}
]
}
1 change: 1 addition & 0 deletions .claude/worktrees/blissful-bartik
Submodule blissful-bartik added at 44e21d
1 change: 1 addition & 0 deletions .claude/worktrees/optimistic-jang
Submodule optimistic-jang added at 0a6d25
1 change: 1 addition & 0 deletions .claude/worktrees/website-iteration
Submodule website-iteration added at 510bef
1 change: 1 addition & 0 deletions .claude/worktrees/zealous-jones
Submodule zealous-jones added at 413d3f
79 changes: 79 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Contributor Agent Guide

This file is for agents working in this repository. It is contributor-facing, not consumer-facing. Keep decisions grounded in the actual repo state, and prefer project-specific instructions over generic agent habits.

## Scope and Precedence

- This guide is for contributors working in the monorepo.
- Public-facing agent context lives under `apps/website/public/` and exists for package users, docs readers, and external tooling.
- When instructions conflict, prefer the most local project instruction available.
- Treat reference docs and copied workflows as inputs, not as truth. Verify against the codebase before acting.

## Operating Principles

- Do not bluff. If something is uncertain, say what is uncertain and verify it from code, docs, or tooling.
- Do the research yourself when the answer can be found locally or by using current documentation.
- Explore first, then edit. For non-trivial work, inspect the relevant files and form a plan before changing code.
- Use applicable workflow guidance before defaulting to generic implementation habits.
- Keep communication direct, calm, and specific. Avoid performative certainty, unnecessary filler, or aggressive phrasing.

## Planning and Execution

- For simple, localized changes, a brief mental plan is fine.
- For anything that spans multiple files, affects behavior, or has unclear boundaries, inspect the codebase and write out a plan before editing.
- Follow existing patterns unless there is a concrete reason to improve them as part of the task.
- Keep changes scoped to the goal. Do not fold unrelated refactors into the same task unless they are required to make the work coherent.
- If you discover the current approach is wrong, adjust course explicitly instead of forcing the original plan through.

## Commands and Tooling

- Prefer setting the tool's working directory over shell patterns like `cd path && command`. In Codex, pass `workdir` directly to the command tool.
- Use the repo's actual package manager and task runner. This repo uses `npm` at the root and `nx` for workspace tasks.
- Prefer `rg` and `rg --files` for search.
- Prefer non-interactive commands.
- Avoid destructive git operations unless explicitly requested.
- Do not substitute other runners when the repo already defines the right command.

## Repo Layout

- `libs/stream-resource`: main Angular library.
- `apps/website`: docs and marketing site.
- `packages/mcp`: MCP server package.
- `e2e/stream-resource-e2e`: end-to-end coverage for the workspace.
- `apps/demo` and `apps/demo-e2e`: demo application and related end-to-end coverage.

## Working in This Repo

- The workspace is Nx-based. Prefer project-scoped commands over broad workspace runs unless the task actually needs broader verification.
- Inspect `project.json`, `nx.json`, and existing scripts before inventing commands.
- If you need Nx-specific syntax or behavior and it is not obvious from local config, verify it from current Nx docs rather than relying on memory.
- Respect generated and public-facing context files. If the task changes docs, API surface, positioning, or package guidance, check whether agent context or docs should be regenerated.

## Docs and Generated Context

- Do not commit generated plans, analyses, or reports unless explicitly requested.
- If docs or public agent guidance changes, check whether `npm run generate-agent-context` should be run.
- If API docs or narrative docs are affected, check whether `npm run generate-api-docs`, `npm run generate-narrative-docs`, or `npm run generate-docs` should be run.
- Do not regenerate files blindly. Run the smallest relevant generator for the change.

## Commits and Review

- Do not make mid-task commits. Group related finished work into a logical commit.
- Do not add co-author metadata unless explicitly requested.
- Before proposing a commit or claiming the task is done, review the diff and verify the relevant commands were actually run.
- If you use delegated review or sub-agents, verify their output yourself before repeating their conclusions.

## Verification

- Do not claim work is complete without fresh verification evidence from relevant commands.
- Verify the smallest relevant surface first, then broaden as needed.
- Prefer repo-native commands. Typical examples in this repo include `npx nx test <project>`, `npx nx lint <project>`, `npx nx build <project>`, and doc generation commands when context files change.
- If a task affects only one project, verify that project first instead of defaulting to the whole workspace.
- Report what you actually verified, and call out anything you could not run.

## Codex Notes

- In Codex, prefer `workdir` over `cd`.
- Use `apply_patch` for targeted edits.
- Read the repo state before editing, especially in a dirty worktree.
- Do not revert user changes you did not make unless explicitly asked.
30 changes: 15 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<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 Stream Resource — The Enterprise Streaming Resource for LangChain and Angular"
width="100%"
/>
</p>
Expand All @@ -11,13 +11,13 @@
</p>

<p align="center">
<a href="https://www.npmjs.com/package/@cacheplane/angular">
<img alt="npm version" src="https://img.shields.io/npm/v/@cacheplane%2Fangular?color=6C8EFF&labelColor=080B14&style=flat-square" />
<a href="https://www.npmjs.com/package/@cacheplane/stream-resource">
<img alt="npm version" src="https://img.shields.io/npm/v/@cacheplane%2Fstream-resource?color=6C8EFF&labelColor=080B14&style=flat-square" />
</a>
<a href="./LICENSE">
<img alt="License: PolyForm Noncommercial + Commercial" src="https://img.shields.io/badge/license-PolyForm%20Noncommercial%20%2B%20Commercial-6C8EFF?labelColor=080B14&style=flat-square" />
</a>
<a href="https://cacheplane.ai">
<a href="https://angular.dev">
<img alt="Angular 20+" src="https://img.shields.io/badge/Angular-20%2B-6C8EFF?labelColor=080B14&style=flat-square" />
</a>
<a href="https://langchain-ai.github.io/langgraph/">
Expand All @@ -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`
Expand All @@ -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({
Expand All @@ -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',
Expand All @@ -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` |
Expand All @@ -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<T>` compatibility | Full duck-type parity | N/A |
| Angular 20+ Signals API | Native | N/A |
| SSR / Server Components | Client-side only | React Server Components (React) |
Expand All @@ -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 → agent() → StreamManager Bridge → LangGraph Platform, with signals returned reactively"
alt="Angular Stream Resource architecture: Angular Component → streamResource() → StreamManager Bridge → LangGraph Platform, with signals returned reactively"
width="100%"
/>
</p>

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

---

Expand All @@ -137,17 +137,17 @@ That's it. `chat.messages()` is an Angular Signal. Bind it directly in your temp

- [Getting Started](https://cacheplane.ai/docs/getting-started)
- [API Reference](https://cacheplane.ai/api-reference)
- [Testing with MockAgentTransport](https://cacheplane.ai/docs/testing)
- [Testing with MockStreamTransport](https://cacheplane.ai/docs/testing)
- [Human-in-the-Loop / Interrupts](https://cacheplane.ai/docs/interrupts)
- [Subagent Streaming](https://cacheplane.ai/docs/subagents)

---

## License

`@cacheplane/angular` is source-available software dual-licensed:
`@cacheplane/stream-resource` is source-available software dual-licensed:

- **PolyForm Noncommercial 1.0.0** — free for noncommercial use (personal projects, academic, research, non-profit internal tooling). See [`LICENSE`](./LICENSE).
- **Angular Agent Framework Commercial License** — required for any for-profit or revenue-generating use. See [`LICENSE-COMMERCIAL`](./LICENSE-COMMERCIAL) and [`COMMERCIAL.md`](./COMMERCIAL.md).
- **Angular Stream Resource Commercial License** — required for any for-profit or revenue-generating use. See [`LICENSE-COMMERCIAL`](./LICENSE-COMMERCIAL) and [`COMMERCIAL.md`](./COMMERCIAL.md).

This is **not** an open-source license. Commercial use — including use in a for-profit product, service, or organization — requires a paid commercial license. See [pricing](https://cacheplane.ai/pricing).
2 changes: 1 addition & 1 deletion apps/cockpit/next-env.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
import "./../../dist/apps/cockpit/.next/types/routes.d.ts";
import "./.next/dev/types/routes.d.ts";

// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
12 changes: 6 additions & 6 deletions apps/website/src/components/shared/Nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { tokens } from '@cacheplane/design-tokens';
const links = [
{ label: 'Pilot to Prod', href: '/pilot-to-prod', external: false },
{ label: 'Docs', href: '/docs', external: false },
{ label: 'API', href: '/docs/agent/api/agent', external: false },
{ label: 'API', href: '/docs/api/stream-resource', external: false },
{ label: 'Examples', href: 'https://cockpit.cacheplane.ai', external: true },
{ label: 'Pricing', href: '/pricing', external: false },
];
Expand Down Expand Up @@ -50,7 +50,7 @@ export function Nav() {
{/* Top bar */}
<div className="flex items-center justify-between px-6 py-4 md:px-8 md:py-5">
<Link href="/" className="font-garamond text-xl font-bold" style={{ color: tokens.colors.textPrimary }}>
🛩️ Angular Agent Framework
Angular Stream Resource
</Link>

{/* Desktop links */}
Expand All @@ -74,7 +74,7 @@ export function Nav() {
{l.label}
</Link>
))}
<a href="https://github.com/cacheplane/angular"
<a href="https://github.com/cacheplane/stream-resource"
target="_blank"
rel="noopener noreferrer"
className="transition-colors"
Expand All @@ -95,10 +95,10 @@ export function Nav() {

{/* Mobile hamburger */}
<button
className="flex md:hidden items-center justify-center"
className="md:hidden"
onClick={() => setOpen(!open)}
aria-label={open ? 'Close menu' : 'Open menu'}
style={{ color: tokens.colors.textPrimary, minWidth: 44, minHeight: 44 }}>
style={{ color: tokens.colors.textPrimary }}>
{open ? <CloseIcon /> : <MenuIcon />}
</button>
</div>
Expand All @@ -125,7 +125,7 @@ export function Nav() {
</Link>
))}
<div className="flex items-center gap-4 pt-2">
<a href="https://github.com/cacheplane/angular"
<a href="https://github.com/cacheplane/stream-resource"
target="_blank"
rel="noopener noreferrer"
style={{ color: tokens.colors.textSecondary }}
Expand Down
1 change: 1 addition & 0 deletions apps/website/tsconfig.tsbuildinfo

Large diffs are not rendered by default.

Loading
Loading