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
75 changes: 69 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
runs-on: ubuntu-latest
outputs:
library: ${{ steps.scope.outputs.library }}
angular_compatibility: ${{ steps.scope.outputs.angular_compatibility }}
website: ${{ steps.scope.outputs.website }}
cockpit: ${{ steps.scope.outputs.cockpit }}
cockpit_examples: ${{ steps.scope.outputs.cockpit_examples }}
Expand Down Expand Up @@ -79,7 +80,7 @@ jobs:
library:
name: Library — lint / test / build
needs: ci-scope
if: github.event_name == 'push' || needs.ci-scope.outputs.library == 'true'
if: github.event_name == 'push' || needs.ci-scope.outputs.library == 'true' || needs.ci-scope.outputs.angular_compatibility == 'true'
runs-on: ubuntu-latest
env:
LIBS: chat,langgraph,ag-ui,render,a2ui,telemetry
Expand All @@ -97,6 +98,60 @@ jobs:
- run: node scripts/verify-release-versions.mjs
- name: DX-coverage — public dev-facing functions must have a JSDoc summary
run: node scripts/check-dx-coverage.mjs
- run: node --test examples/chat/smoke/*.spec.mjs scripts/verify-angular-support.spec.mjs
- run: node scripts/verify-angular-support.mjs
- name: Upload production library artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: threadplane-library-dist
path: dist/libs
if-no-files-found: error
retention-days: 1

angular-compatibility:
name: 'Angular ${{ matrix.angular }} — packaged consumer'
needs: [ci-scope, library]
if: github.event_name == 'push' || needs.ci-scope.outputs.angular_compatibility == 'true'
runs-on: ubuntu-latest
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
angular: [20, 21, 22]
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-node@53b83947a5a98c8d113130e565377fae1a50d02f # v6.3.0
with:
node-version: 22.22.3
cache: npm
- run: npm ci
- name: Download production library artifact
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0
with:
name: threadplane-library-dist
path: dist/libs
- name: Install Chromium
run: npx playwright install --with-deps chromium
- name: Generate, install, build, and run consumer
run: >-
node examples/chat/smoke/cli.mjs
--non-interactive --fresh
--target "${{ runner.temp }}/threadplane-angular-${{ matrix.angular }}"
--local-dist-root dist/libs
--angular-major "${{ matrix.angular }}"
--install --build --runtime
- name: Upload compatibility diagnostics on failure
if: failure()
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: angular-${{ matrix.angular }}-compatibility-diagnostics
path: |
${{ runner.temp }}/threadplane-angular-${{ matrix.angular }}/package.json
${{ runner.temp }}/threadplane-angular-${{ matrix.angular }}/package-lock.json
${{ runner.temp }}/threadplane-angular-${{ matrix.angular }}/runtime-smoke.png
${{ runner.temp }}/threadplane-angular-${{ matrix.angular }}/runtime-smoke-trace.zip
if-no-files-found: warn
retention-days: 7

website:
name: Website — lint / test / build
Expand Down Expand Up @@ -240,7 +295,7 @@ jobs:
- run: npx nx run examples-chat-python:smoke --skip-nx-cache

examples-chat-e2e:
name: "examples/chat — e2e (${{ matrix.shard }}/4)"
name: 'examples/chat — e2e (${{ matrix.shard }}/4)'
needs: ci-scope
if: github.event_name == 'push' || needs.ci-scope.outputs.examples_chat == 'true'
runs-on: ubuntu-latest
Expand Down Expand Up @@ -287,7 +342,7 @@ jobs:
retention-days: 7

examples-chat-e2e-summary:
name: "examples/chat — e2e"
name: 'examples/chat — e2e'
needs: [ci-scope, examples-chat-e2e]
if: always() && (github.event_name == 'push' || needs.ci-scope.outputs.examples_chat == 'true')
runs-on: ubuntu-latest
Expand All @@ -301,7 +356,7 @@ jobs:
echo "All examples-chat-e2e matrix expansions passed."

examples-ag-ui-e2e:
name: "examples/ag-ui — e2e"
name: 'examples/ag-ui — e2e'
needs: ci-scope
# No dedicated ci-scope output exists for examples/ag-ui yet, so this job
# runs on every push and pull_request rather than being scope-gated. It is
Expand Down Expand Up @@ -383,7 +438,7 @@ jobs:
--full-fleet "${{ steps.refs.outputs.full }}"

cockpit-e2e:
name: "Cockpit — e2e (${{ matrix.cap.angular }})"
name: 'Cockpit — e2e (${{ matrix.cap.angular }})'
needs: [ci-scope, cockpit-e2e-dispatcher]
if: github.event_name == 'push' || needs.ci-scope.outputs.cockpit_e2e == 'true'
runs-on: ubuntu-latest
Expand Down Expand Up @@ -431,7 +486,7 @@ jobs:
retention-days: 7

cockpit-e2e-summary:
name: "Cockpit — e2e"
name: 'Cockpit — e2e'
needs: [ci-scope, cockpit-e2e]
if: always() && (github.event_name == 'push' || needs.ci-scope.outputs.cockpit_e2e == 'true')
runs-on: ubuntu-latest
Expand Down Expand Up @@ -471,6 +526,7 @@ jobs:
needs:
- ci-scope
- library
- angular-compatibility
- website
- cockpit
- cockpit-examples-build
Expand All @@ -488,6 +544,7 @@ jobs:
env:
RESULT_CI_SCOPE: ${{ needs.ci-scope.result }}
RESULT_LIBRARY: ${{ needs.library.result }}
RESULT_ANGULAR_COMPATIBILITY: ${{ needs.angular-compatibility.result }}
RESULT_WEBSITE: ${{ needs.website.result }}
RESULT_COCKPIT: ${{ needs.cockpit.result }}
RESULT_COCKPIT_EXAMPLES: ${{ needs.cockpit-examples-build.result }}
Expand All @@ -499,6 +556,7 @@ jobs:
RESULT_WEBSITE_E2E: ${{ needs.website-e2e.result }}
RESULT_POSTHOG: ${{ needs.posthog-sync-plan.result }}
SCOPE_LIBRARY: ${{ needs.ci-scope.outputs.library }}
SCOPE_ANGULAR_COMPATIBILITY: ${{ needs.ci-scope.outputs.angular_compatibility }}
SCOPE_WEBSITE: ${{ needs.ci-scope.outputs.website }}
SCOPE_COCKPIT: ${{ needs.ci-scope.outputs.cockpit }}
SCOPE_COCKPIT_EXAMPLES: ${{ needs.ci-scope.outputs.cockpit_examples }}
Expand Down Expand Up @@ -545,6 +603,11 @@ jobs:

require_always "CI scope" "$RESULT_CI_SCOPE"
require_scoped "library" "Library — lint / test / build" "$RESULT_LIBRARY" "$SCOPE_LIBRARY"
require_scoped \
"angular_compatibility" \
"Angular compatibility matrix" \
"$RESULT_ANGULAR_COMPATIBILITY" \
"$SCOPE_ANGULAR_COMPATIBILITY"
require_scoped "website" "Website — lint / test / build" "$RESULT_WEBSITE" "$SCOPE_WEBSITE"
require_scoped "cockpit" "Cockpit — build / test" "$RESULT_COCKPIT" "$SCOPE_COCKPIT"
require_scoped "cockpit_examples" "Cockpit — build all examples" "$RESULT_COCKPIT_EXAMPLES" "$SCOPE_COCKPIT_EXAMPLES"
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<img alt="npm version" src="https://img.shields.io/npm/v/@threadplane%2Flanggraph?color=6C8EFF&labelColor=080B14&style=flat-square" />
</a>
<a href="https://angular.dev">
<img alt="Angular 20+" src="https://img.shields.io/badge/Angular-20%2B-6C8EFF?labelColor=080B14&style=flat-square" />
<img alt="Angular 20 | 21 | 22" src="https://img.shields.io/badge/Angular-20%20%7C%2021%20%7C%2022-6C8EFF?labelColor=080B14&style=flat-square" />
</a>
<a href="https://langchain-ai.github.io/langgraph/">
<img alt="LangGraph" src="https://img.shields.io/badge/LangGraph-SDK-6C8EFF?labelColor=080B14&style=flat-square" />
Expand Down Expand Up @@ -45,7 +45,7 @@ Threadplane is a production-ready agent UI framework for Angular. `@threadplane/
npm install @threadplane/langgraph @threadplane/chat
```

**Peer dependencies:** `@angular/core ^20.0.0 || ^21.0.0`, `@langchain/core ^1.1.33`, `@langchain/langgraph-sdk ^1.7.4`, `rxjs ~7.8.0`
**Peer dependencies:** `@angular/core ^20.0.0 || ^21.0.0 || ^22.0.0`, `@langchain/core ^1.1.33`, `@langchain/langgraph-sdk ^1.7.4`, `rxjs ~7.8.0`

---

Expand Down
49 changes: 28 additions & 21 deletions apps/website/content/docs/ag-ui/getting-started/installation.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Installation

Supported Angular majors: 20, 21, and 22.

Use a Node.js version supported by the selected Angular major. Angular 22 supports Node.js ^22.22.3, ^24.15.0, or ^26.0.0. See the [Angular compatibility matrix](https://angular.dev/reference/versions).

## Prerequisites

- Angular 20 or later
- Node.js 22+
- An AG-UI-compatible backend running locally or remotely (CrewAI, Mastra, Microsoft Agent Framework, AG2, Pydantic AI, AWS Strands, or your own subclass of `AbstractAgent`)

## Install packages
Expand All @@ -19,13 +22,13 @@ npm install @threadplane/chat @threadplane/ag-ui @ag-ui/client @ag-ui/core marke

`@threadplane/ag-ui` declares the following peer dependencies:

| Package | Version |
|---|---|
| `@threadplane/chat` | `*` |
| `@angular/core` | `^20.0.0 \|\| ^21.0.0` |
| `@ag-ui/client` | `*` |
| `@ag-ui/core` | `*` |
| `rxjs` | `~7.8.0` |
| Package | Version |
| ------------------- | ----------------------------------- |
| `@threadplane/chat` | `*` |
| `@angular/core` | `^20.0.0 \|\| ^21.0.0 \|\| ^22.0.0` |
| `@ag-ui/client` | `*` |
| `@ag-ui/core` | `*` |
| `rxjs` | `~7.8.0` |

## Configure the provider

Expand All @@ -38,20 +41,20 @@ import { provideAgent } from '@threadplane/ag-ui';
export const appConfig: ApplicationConfig = {
providers: [
provideAgent({
url: 'http://localhost:3000/agent', // your AG-UI backend
url: 'http://localhost:3000/agent', // your AG-UI backend
}),
],
};
```

`provideAgent` accepts:

| Option | Type | Description |
|---|---|---|
| `url` | `string` | **Required.** AG-UI backend HTTP/SSE endpoint. |
| `agentId` | `string` | Optional. Identifies a specific agent on the backend. |
| `threadId` | `string` | Optional. Resume an existing conversation thread. |
| `headers` | `Record<string, string>` | Optional. Custom request headers (auth, tracing). |
| Option | Type | Description |
| ----------- | ------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url` | `string` | **Required.** AG-UI backend HTTP/SSE endpoint. |
| `agentId` | `string` | Optional. Identifies a specific agent on the backend. |
| `threadId` | `string` | Optional. Resume an existing conversation thread. |
| `headers` | `Record<string, string>` | Optional. Custom request headers (auth, tracing). |
| `telemetry` | `AgentRuntimeTelemetrySink \| false` | Optional. App-owned telemetry sink — opt-in, emits nothing unless supplied. See [`@threadplane/telemetry`](/docs/telemetry/getting-started/introduction). |

## Use in a component
Expand Down Expand Up @@ -94,18 +97,22 @@ export const appConfig: ApplicationConfig = {

`provideFakeAgent` accepts:

| Option | Type | Description |
|---|---|---|
| `tokens` | `string[]` | Optional. Tokens streamed back as the assistant reply. |
| `reasoningTokens` | `string[]` | Optional. Reasoning chunks emitted before the text reply (defaults to `[]`). |
| `delayMs` | `number` | Optional. Milliseconds between successive token emissions (defaults to `60`). |
| Option | Type | Description |
| ----------------- | ---------- | ----------------------------------------------------------------------------- |
| `tokens` | `string[]` | Optional. Tokens streamed back as the assistant reply. |
| `reasoningTokens` | `string[]` | Optional. Reasoning chunks emitted before the text reply (defaults to `[]`). |
| `delayMs` | `number` | Optional. Milliseconds between successive token emissions (defaults to `60`). |

## Custom transport

If you have a backend that speaks AG-UI but not over HTTP, subclass `AbstractAgent` directly and feed it to `toAgent`:

```ts
import { AbstractAgent, type RunAgentInput, type BaseEvent } from '@ag-ui/client';
import {
AbstractAgent,
type RunAgentInput,
type BaseEvent,
} from '@ag-ui/client';
import { Observable } from 'rxjs';
import { toAgent } from '@threadplane/ag-ui';

Expand Down
36 changes: 32 additions & 4 deletions apps/website/content/docs/chat/getting-started/installation.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,25 @@ or runtime key.

## Prerequisites

- Angular 20 or 21
- Node.js 18 or later
- An agent backend, or `mockAgent()` while you build the UI
Supported Angular majors: 20, 21, and 22.

<Steps>
<Step title="Angular 20 or later">
`@threadplane/chat` uses Angular Signals, `input()`, and `contentChildren()`. Run `ng version` to confirm. Upgrade with `ng update @angular/core @angular/cli` if you're below 20.
</Step>
<Step title="Node.js compatibility">
Use a Node.js version supported by the selected Angular major. Angular 22 supports Node.js ^22.22.3, ^24.15.0, or ^26.0.0. See the [Angular compatibility matrix](https://angular.dev/reference/versions).
</Step>
<Step title="A running agent backend (or a mock)">
The chat UI needs something to talk to. Two officially supported adapters cover virtually every backend:

- **`@threadplane/langgraph`** — pick this if your backend is LangGraph or LangGraph Platform.
- **`@threadplane/ag-ui`** — pick this for an AG-UI-compatible backend such as CrewAI, Mastra, Microsoft Agent Framework, AG2, Pydantic AI, or AWS Strands.

Both adapters expose the same `Agent` contract to `@threadplane/chat`, so swapping later is a one-line change. If you don't have a backend yet, use `mockAgent()` from `@threadplane/chat` to wire up the UI first.

</Step>
</Steps>

## 1. Install the packages

Expand All @@ -24,10 +40,22 @@ npm install @threadplane/chat @threadplane/ag-ui @ag-ui/client @ag-ui/core marke
`@json-render/core`, RxJS, and Zod as peer dependencies. npm 7 and later
install required peers automatically. KaTeX is optional.

<Callout type="info" title="Full peer dependency list">
`@threadplane/chat` declares peers on `@angular/core`, `@angular/common`,
`@angular/platform-browser`, `@angular/router` (all `^20.0.0 || ^21.0.0 ||
^22.0.0`), plus `@threadplane/render`, `@threadplane/a2ui`,
`@json-render/core` (`^0.16.0`), `@langchain/core` (`^1.1.33`), `rxjs`
(`~7.8.0`), `marked` (`^15 || ^16`), `zod` (`^3.25.0`), and optional `katex`
(`^0.16.0 || ^0.17.0`). npm 7+ installs all required peers automatically.
</Callout>

## 2. Configure the runtime and chat

```ts
import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import {
ApplicationConfig,
provideZonelessChangeDetection,
} from '@angular/core';
import { provideAgent } from '@threadplane/langgraph';
import { provideChat } from '@threadplane/chat';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ Detailed setup guide for `injectAgent()` in your Angular application.

## Requirements

Supported Angular majors: 20, 21, and 22.

<Steps>
<Step title="Angular 20+">
`injectAgent()` uses Angular Signals and the modern injection context API. Angular 20 or later is required.
</Step>
<Step title="Node.js 18+">
Required for the build toolchain and package installation.
<Step title="Node.js compatibility">
Use a Node.js version supported by the selected Angular major. Angular 22 supports Node.js ^22.22.3, ^24.15.0, or ^26.0.0. See the [Angular compatibility matrix](https://angular.dev/reference/versions).
</Step>
<Step title="LangGraph Platform">
A running LangGraph agent reachable over HTTP. Local (`langgraph dev`) or deployed (LangGraph Cloud) both work.
Expand All @@ -31,7 +33,7 @@ npm install @threadplane/langgraph @threadplane/chat @langchain/core @langchain/
| Package | Version |
|---------|---------|
| `@threadplane/chat` | `*` |
| `@angular/core` | `^20.0.0 \|\| ^21.0.0` |
| `@angular/core` | `^20.0.0 \|\| ^21.0.0 \|\| ^22.0.0` |
| `@langchain/core` | `^1.1.33` |
| `@langchain/langgraph-sdk` | `^1.7.4` |
| `rxjs` | `~7.8.0` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ Detailed setup guide for `@threadplane/render` in your Angular application.

## Requirements

Supported Angular majors: 20, 21, and 22.

<Steps>
<Step title="Angular 20+">
`@threadplane/render` uses Angular Signals, the `input()` function, and the `NgComponentOutlet` directive. Angular 20 or later is required.
</Step>
<Step title="Node.js 18+">
Required for the build toolchain and package installation.
<Step title="Node.js compatibility">
Use a Node.js version supported by the selected Angular major. Angular 22 supports Node.js ^22.22.3, ^24.15.0, or ^26.0.0. See the [Angular compatibility matrix](https://angular.dev/reference/versions).
</Step>
</Steps>

Expand All @@ -25,8 +27,8 @@ The library requires the following peer dependencies:

| Package | Version |
|---------|---------|
| `@angular/core` | `^20.0.0` or `^21.0.0` |
| `@angular/common` | `^20.0.0` or `^21.0.0` |
| `@angular/core` | `^20.0.0`, `^21.0.0`, or `^22.0.0` |
| `@angular/common` | `^20.0.0`, `^21.0.0`, or `^22.0.0` |
| `@json-render/core` | `^0.16.0` |

<Callout type="info" title="Angular packages">
Expand Down
Loading
Loading