diff --git a/README.md b/README.md index 30d253b0..10e1fc50 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@

- Agent UI primitives and LangGraph streaming adapters for Angular + Agent UI for Angular — Production-ready chat, threads, and generative UI for AI agents.

@@ -27,7 +27,9 @@ --- -`agent()` is the Angular equivalent of LangGraph's React `useStream()` hook, projected into a runtime-neutral `Agent` contract consumed by `@ngaf/chat`. Drop it into any Angular 20+ component, point it at your LangGraph Platform endpoint, and get signal-driven access to messages, status, tool calls, interrupts, subagents, regenerate, and thread history. +ThreadPlane is a production-ready agent UI framework for Angular. Use `@ngaf/chat` for chat surfaces, `@ngaf/langgraph` for LangGraph-backed agents, `@ngaf/ag-ui` for AG-UI event streams, and `@ngaf/render` for generative UI that stays inside your Angular design system. + +When you are building on LangGraph, `agent()` is the Angular equivalent of LangGraph's React `useStream()` hook, projected into a runtime-neutral `Agent` contract consumed by `@ngaf/chat`. Drop it into any Angular 20+ component, point it at your LangGraph Platform endpoint, and get signal-driven access to messages, status, tool calls, interrupts, subagents, regenerate, and thread history. --- diff --git a/apps/website/content/AGENTS.md.template b/apps/website/content/AGENTS.md.template index a867ab1b..9a1b1289 100644 --- a/apps/website/content/AGENTS.md.template +++ b/apps/website/content/AGENTS.md.template @@ -1,6 +1,6 @@ # Agent UI for Angular v@VERSION@ -Agent UI primitives and LangGraph streaming adapters for Angular. +Production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI for Angular agent apps. ## Install npm install @ngaf/chat @ngaf/langgraph diff --git a/apps/website/content/CLAUDE.md.template b/apps/website/content/CLAUDE.md.template index a867ab1b..9a1b1289 100644 --- a/apps/website/content/CLAUDE.md.template +++ b/apps/website/content/CLAUDE.md.template @@ -1,6 +1,6 @@ # Agent UI for Angular v@VERSION@ -Agent UI primitives and LangGraph streaming adapters for Angular. +Production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI for Angular agent apps. ## Install npm install @ngaf/chat @ngaf/langgraph diff --git a/apps/website/content/docs/agent/getting-started/introduction.mdx b/apps/website/content/docs/agent/getting-started/introduction.mdx index 56eeffd1..798fdf12 100644 --- a/apps/website/content/docs/agent/getting-started/introduction.mdx +++ b/apps/website/content/docs/agent/getting-started/introduction.mdx @@ -1,6 +1,6 @@ # Introduction -Agent is the Signal-native streaming library for Angular 20+ — built natively for LangGraph, without React translation layers. Build streaming AI applications with Angular Signals, connect to LangGraph agents, and ship production-ready frontends for your AI products. +Agent is the Angular adapter layer for production-ready agent UI surfaces: chat, durable threads, interrupts, subagents, planning, memory, and generative UI. Build complete Angular 20+ agent applications with Signals, connect them to LangGraph agents, and keep the UI inside Angular templates, dependency injection, and your design system. This guide walks you through the complete workflow: build a LangGraph agent in Python, run it locally, connect it to an Angular app with agent(), and deploy to production. diff --git a/apps/website/emails/angular-download.ts b/apps/website/emails/angular-download.ts index 31093ee7..e3d60e6d 100644 --- a/apps/website/emails/angular-download.ts +++ b/apps/website/emails/angular-download.ts @@ -5,7 +5,7 @@ const DOWNLOAD_URL = 'https://threadplane.ai/whitepapers/angular.pdf'; export function angularDownloadHtml(name?: string): string { return wrapEmail({ body: ` -

Your Enterprise Guide to Agent Streaming

+

Your Enterprise Guide to Agent UI in Angular

${name ? `Hi ${esc(name)}, t` : 'T'}he guide covers six chapters: the last-mile problem, the agent() API, thread persistence, interrupt flows, full LangGraph feature coverage, and deterministic testing.

Download the Guide diff --git a/apps/website/emails/drip-chat-followup.ts b/apps/website/emails/drip-chat-followup.ts index e61d144a..63323afd 100644 --- a/apps/website/emails/drip-chat-followup.ts +++ b/apps/website/emails/drip-chat-followup.ts @@ -8,7 +8,7 @@ export function dripChatFollowupHtml(day: number): { subject: string; html: stri body: `

Chat Guide Follow-up

Did you read Chapter 2 on batteries-included components?

-

Chapter 2 covers the batteries-included component library — message bubbles, streaming indicators, thread lists, and input controls that are pre-wired to LangGraph state. Drop them in and your chat UI works on day one.

+

Chapter 2 covers the batteries-included component library — message bubbles, streaming indicators, thread lists, and input controls that are pre-wired to agent state. Drop them in and your chat UI works on day one.

Read the Docs → `, showUnsubscribe: true, diff --git a/apps/website/emails/email-wrapper.ts b/apps/website/emails/email-wrapper.ts index 499589ba..014af797 100644 --- a/apps/website/emails/email-wrapper.ts +++ b/apps/website/emails/email-wrapper.ts @@ -18,7 +18,7 @@ export function wrapEmail(opts: {
${opts.body}
-

Agent UI for Angular — Signal-native streaming for LangGraph.

+

Agent UI for Angular — Production-ready chat, threads, and generative UI for AI agents.

${opts.showUnsubscribe ? '

Unsubscribe

' : ''}
diff --git a/apps/website/emails/whitepaper-download.ts b/apps/website/emails/whitepaper-download.ts index 78879de2..f0386cd6 100644 --- a/apps/website/emails/whitepaper-download.ts +++ b/apps/website/emails/whitepaper-download.ts @@ -5,7 +5,7 @@ const DOWNLOAD_URL = 'https://threadplane.ai/whitepaper.pdf'; export function whitepaperDownloadHtml(name?: string): string { return wrapEmail({ body: ` -

Your Angular Agent Readiness Guide

+

Your Enterprise Agent UI Guide for Angular

${name ? `Hi ${esc(name)}, t` : 'T'}he guide covers six production-readiness dimensions: streaming state, thread persistence, tool-call rendering, human approval flows, generative UI, and deterministic testing.

Download the Guide diff --git a/apps/website/public/AGENTS.md b/apps/website/public/AGENTS.md index 7d693507..544b2463 100644 --- a/apps/website/public/AGENTS.md +++ b/apps/website/public/AGENTS.md @@ -1,6 +1,6 @@ # Agent UI for Angular v0.0.40 -Agent UI primitives and LangGraph streaming adapters for Angular. +Production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI for Angular agent apps. ## Install npm install @ngaf/chat @ngaf/langgraph diff --git a/apps/website/public/CLAUDE.md b/apps/website/public/CLAUDE.md index 7d693507..544b2463 100644 --- a/apps/website/public/CLAUDE.md +++ b/apps/website/public/CLAUDE.md @@ -1,6 +1,6 @@ # Agent UI for Angular v0.0.40 -Agent UI primitives and LangGraph streaming adapters for Angular. +Production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI for Angular agent apps. ## Install npm install @ngaf/chat @ngaf/langgraph diff --git a/apps/website/public/assets/arch-diagram.svg b/apps/website/public/assets/arch-diagram.svg index 02f9d202..e4c923b0 100644 --- a/apps/website/public/assets/arch-diagram.svg +++ b/apps/website/public/assets/arch-diagram.svg @@ -33,7 +33,7 @@ font-size="15" font-weight="700" fill="#6C8EFF">agent() Signal-native state + font-size="11" fill="#4A527A">Agent UI state @ngaf/langgraph diff --git a/apps/website/public/assets/hero.svg b/apps/website/public/assets/hero.svg index 2c3f1d39..92840981 100644 --- a/apps/website/public/assets/hero.svg +++ b/apps/website/public/assets/hero.svg @@ -24,7 +24,7 @@ font-style="italic" fill="#8B96C8" opacity="0.9" - >Agent UI for Angular — for LangGraph + >Agent UI for Angular — Production-ready agent UI diff --git a/apps/website/public/whitepaper-preview.html b/apps/website/public/whitepaper-preview.html index ab247c7f..df46dbeb 100644 --- a/apps/website/public/whitepaper-preview.html +++ b/apps/website/public/whitepaper-preview.html @@ -20,9 +20,9 @@
-
@ngaf/langgraph · Production Readiness Guide
-

From
Prototype
to
Production

-

The Angular Agent Readiness Guide

+
ThreadPlane · Enterprise Angular Agent UI
+

Agent
UI
for
Angular

+

Production-ready chat, threads, and generative UI for AI agents

threadplane.ai · 2026
@@ -65,7 +65,7 @@

-
@ngaf/langgraph · Enterprise Guide
-

The
Enterprise
Guide
to
Agent
Streaming
in
Angular

-

Ship LangGraph agents in Angular — without building the plumbing

+
ThreadPlane · Angular Agent UI Guide
+

The
Enterprise
Guide
to
Agent
UI
in
Angular

+

Ship LangGraph and AG-UI-compatible agents without building the plumbing

threadplane.ai · 2026
@@ -145,7 +145,7 @@

The Alternative

With `agent()`:

readonly chat = agent({ assistantId: 'chat_agent' });
 
-

The signal-native design eliminates the subscription lifecycle entirely. When the component destroys, the signals become inert. No `takeUntilDestroyed()`. No `ngOnDestroy`. The framework handles it.

+

The Angular signals-based design eliminates the subscription lifecycle entirely. When the component destroys, the signals become inert. No `takeUntilDestroyed()`. No `ngOnDestroy`. The framework handles it.

Chapter 3
diff --git a/apps/website/public/whitepapers/angular.pdf b/apps/website/public/whitepapers/angular.pdf index 3a252030..7c44548a 100644 Binary files a/apps/website/public/whitepapers/angular.pdf and b/apps/website/public/whitepapers/angular.pdf differ diff --git a/apps/website/public/whitepapers/chat.pdf b/apps/website/public/whitepapers/chat.pdf index a5c19f98..ae438d20 100644 Binary files a/apps/website/public/whitepapers/chat.pdf and b/apps/website/public/whitepapers/chat.pdf differ diff --git a/apps/website/public/whitepapers/render.pdf b/apps/website/public/whitepapers/render.pdf index 8cd4aded..daea95f2 100644 Binary files a/apps/website/public/whitepapers/render.pdf and b/apps/website/public/whitepapers/render.pdf differ diff --git a/apps/website/scripts/generate-whitepaper.ts b/apps/website/scripts/generate-whitepaper.ts index 67dd779d..33ce91e7 100644 --- a/apps/website/scripts/generate-whitepaper.ts +++ b/apps/website/scripts/generate-whitepaper.ts @@ -67,9 +67,9 @@ interface WhitepaperConfig { const WHITEPAPERS: Record = { overview: { id: 'overview', - title: 'From Prototype to Production', - subtitle: 'The Angular Agent Readiness Guide', - eyebrow: '@ngaf/langgraph · Production Readiness Guide', + title: 'Agent UI for Angular', + subtitle: 'Production-ready chat, threads, and generative UI for AI agents', + eyebrow: 'ThreadPlane · Enterprise Angular Agent UI', coverGradient: 'linear-gradient(135deg, #fafbfc 0%, #eaf3ff 100%)', outputPdf: 'apps/website/public/whitepaper.pdf', outputHtml: 'apps/website/public/whitepaper-preview.html', @@ -77,15 +77,15 @@ const WHITEPAPERS: Record = { { id: 'streaming-state', title: 'Streaming State Management', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Streaming State Management -Context: Angular teams building LangGraph-powered agents must wire SSE event streams into reactive UI. Without the right primitives, they end up with custom zone-patching, manual subscription management, and brittle token accumulation logic that breaks under load. +Context: Angular teams building AI agent applications must wire streaming transports into reactive chat, thread, approval, and generative UI surfaces. Without the right primitives, they end up with custom zone-patching, manual subscription management, and brittle token accumulation logic that breaks under load. Cover: - Why streaming state is hard in Angular (zone.js, change detection, timing) -- The signals-native approach: how agent() exposes messages() as Signal +- The Angular signals approach: how agent() exposes messages() as Signal - How isLoading() lets developers drive loading UI without polling - Code example: minimal agent() setup (TypeScript snippet, 8-12 lines) - Production checklist item: "Are your message signals OnPush-compatible?" @@ -95,7 +95,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'thread-persistence', title: 'Thread Persistence', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Thread Persistence @@ -114,7 +114,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'tool-call-rendering', title: 'Tool-Call Rendering', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Tool-Call Rendering @@ -133,7 +133,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'human-approval-flows', title: 'Human Approval Flows', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Human Approval Flows (Interrupts) @@ -153,7 +153,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'generative-ui', title: 'Generative UI', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Generative UI @@ -172,7 +172,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'deterministic-testing', title: 'Deterministic Testing', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "From Prototype to Production: The Angular Agent Readiness Guide". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "Agent UI for Angular: Production-ready chat, threads, and generative UI for AI agents". Chapter topic: Deterministic Testing @@ -193,9 +193,9 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi angular: { id: 'angular', - title: 'The Enterprise Guide to Agent Streaming in Angular', - subtitle: 'Ship LangGraph agents in Angular — without building the plumbing', - eyebrow: '@ngaf/langgraph · Enterprise Guide', + title: 'The Enterprise Guide to Agent UI in Angular', + subtitle: 'Ship LangGraph and AG-UI-compatible agents without building the plumbing', + eyebrow: 'ThreadPlane · Angular Agent UI Guide', coverGradient: 'linear-gradient(135deg, #fafbfc 0%, #eaf3ff 100%)', outputPdf: 'apps/website/public/whitepapers/angular.pdf', outputHtml: 'apps/website/public/whitepapers/angular-preview.html', @@ -203,11 +203,11 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'last-mile-problem', title: 'The Last-Mile Problem', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: The Last-Mile Problem -Context: Teams have built powerful LangGraph backends with sophisticated agent graphs, tool calling, and memory. Then they hit Angular. SSE streams don't integrate cleanly with zone.js. Signals and change detection are at odds with streaming event sequences. The backend works — the frontend gap is real and expensive. +Context: Teams have built powerful agent backends with sophisticated graphs, tool calling, memory, and AG-UI-compatible interaction patterns. Then they hit Angular. SSE streams don't integrate cleanly with zone.js. Signals and change detection are at odds with streaming event sequences. The backend works — the frontend gap is real and expensive. Cover: - Why SSE + Angular zones is a zone pollution problem, not a configuration problem @@ -222,16 +222,16 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'agent-api', title: 'The agent() API', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: The agent() API -Context: @ngaf/langgraph exposes a signal-native API for streaming LangGraph agents into Angular components. The core primitive is agent() — a function that returns reactive signals wired directly to the agent stream, with no manual subscription management, no zone-patching, and no token accumulation logic. +Context: @ngaf/langgraph exposes an Angular signals-based API for connecting LangGraph agents to Angular components. The core primitive is agent() — a function that returns reactive signals wired directly to the agent stream, with no manual subscription management, no zone-patching, and no token accumulation logic. Cover: - How agent() returns a LangGraphAgent with typed signals: messages(), isLoading(), error(), interrupt(), and langGraph* raw signals - The provideAgent() provider and how it configures the agent endpoint and stream transport -- Why the signal-native design works with OnPush change detection out of the box +- Why the Angular signals design works with OnPush change detection out of the box - How to bind agent state directly in Angular templates without async pipe or manual subscriptions - Code example: minimal agent() setup with template binding (10-14 lines) - The contrast: what the equivalent hand-rolled code looks like vs. agent() in 3 lines @@ -241,7 +241,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'thread-persistence-memory', title: 'Thread Persistence & Memory', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: Thread Persistence & Memory @@ -261,7 +261,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'interrupt-approval-flows', title: 'Interrupt & Approval Flows', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: Interrupt & Approval Flows @@ -280,7 +280,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'full-langgraph-coverage', title: 'Full LangGraph Feature Coverage', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: Full LangGraph Feature Coverage @@ -299,7 +299,7 @@ Tone: Direct, technical, peer-to-peer. No fluff. Audience is senior Angular engi { id: 'deterministic-testing-angular', title: 'Deterministic Testing', - prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent Streaming in Angular". + prompt: `Write a 400-600 word chapter for an engineering white paper titled "The Enterprise Guide to Agent UI in Angular". Chapter topic: Deterministic Testing diff --git a/apps/website/src/app/angular/page.tsx b/apps/website/src/app/angular/page.tsx index 139cc048..59a88133 100644 --- a/apps/website/src/app/angular/page.tsx +++ b/apps/website/src/app/angular/page.tsx @@ -9,11 +9,11 @@ import { FeatureBlock } from '../../components/landing/FeatureBlock'; import { WhitePaperBlock } from '../../components/landing/WhitePaperBlock'; import { FinalCTA } from '../../components/landing/FinalCTA'; import { AngularCodeShowcase } from '../../components/landing/angular/AngularCodeShowcase'; -import { createPageMetadata } from '../../lib/site-metadata'; +import { createPageMetadata, SHORT_POSITIONING_DESCRIPTION } from '../../lib/site-metadata'; export const metadata = createPageMetadata({ - title: '@ngaf/langgraph — Agent Streaming for Angular', - description: 'Ship LangGraph agents in Angular. Signal-native streaming, thread persistence, interrupts, and deterministic testing.', + title: '@ngaf/langgraph — Agent UI for Angular', + description: SHORT_POSITIONING_DESCRIPTION, pathname: '/angular', type: 'website', }); @@ -39,7 +39,7 @@ export default async function AngularPage() { letterSpacing: '-0.02em', }} > - Signal-native streaming for Angular. + LangGraph agent UI for Angular.

- Ship LangGraph agents inside your Angular 20+ app. Thread state, interrupts, branch/history, and tool progress — all surfaced as signals. + Ship LangGraph agents inside your Angular 20+ app with headless chat, durable threads, interrupts, branch/history, tool progress, and generative UI.

diff --git a/apps/website/src/app/api/email-preview/route.ts b/apps/website/src/app/api/email-preview/route.ts index 27319807..d10f0eb4 100644 --- a/apps/website/src/app/api/email-preview/route.ts +++ b/apps/website/src/app/api/email-preview/route.ts @@ -12,7 +12,7 @@ import { dripWhitepaperFollowupHtml } from '../../../../emails/drip-whitepaper-f const TEMPLATES: Record { subject: string; html: string }> = { 'whitepaper-download': () => ({ - subject: 'Your Angular Agent Readiness Guide', + subject: 'Your Enterprise Agent UI Guide for Angular', html: whitepaperDownloadHtml('Brian'), }), 'newsletter-welcome': () => ({ diff --git a/apps/website/src/app/api/whitepaper-signup/route.ts b/apps/website/src/app/api/whitepaper-signup/route.ts index 26821d71..db8c4ba4 100644 --- a/apps/website/src/app/api/whitepaper-signup/route.ts +++ b/apps/website/src/app/api/whitepaper-signup/route.ts @@ -23,8 +23,8 @@ const DOWNLOAD_EMAILS: Record string> = { }; const DOWNLOAD_SUBJECTS: Record = { - overview: 'Your Angular Agent Readiness Guide', - angular: 'Your Enterprise Guide to Agent Streaming', + overview: 'Your Enterprise Agent UI Guide for Angular', + angular: 'Your Enterprise Guide to Agent UI in Angular', render: 'Your Enterprise Guide to Generative UI', chat: 'Your Enterprise Guide to Agent Chat Interfaces', }; diff --git a/apps/website/src/app/layout.tsx b/apps/website/src/app/layout.tsx index 17321ba2..82194bd2 100644 --- a/apps/website/src/app/layout.tsx +++ b/apps/website/src/app/layout.tsx @@ -4,7 +4,14 @@ import './global.css'; import { Nav } from '../components/shared/Nav'; import { Footer } from '../components/shared/Footer'; import { AnnouncementToast } from '../components/shared/AnnouncementToast'; -import { DEFAULT_SOCIAL_IMAGE, SITE_NAME, SITE_ORIGIN } from '../lib/site-metadata'; +import { + DEFAULT_META_DESCRIPTION, + DEFAULT_SOCIAL_IMAGE, + LONG_SUBHEAD, + PRIMARY_TAGLINE, + SITE_NAME, + SITE_ORIGIN, +} from '../lib/site-metadata'; const garamond = EB_Garamond({ subsets: ['latin'], @@ -25,14 +32,14 @@ const mono = JetBrains_Mono({ export const metadata: Metadata = { metadataBase: new URL(SITE_ORIGIN), - title: 'Agent UI for Angular — Signal-Native Streaming for Angular + LangGraph', - description: 'The enterprise Angular agent framework for LangChain. Signal-native streaming, thread persistence, and production patterns for Angular 20+.', + title: PRIMARY_TAGLINE, + description: DEFAULT_META_DESCRIPTION, icons: { icon: 'data:image/svg+xml,🛩️', }, openGraph: { title: 'Agent UI for Angular', - description: 'Signal-native streaming for LangGraph — production patterns your Angular team can own.', + description: LONG_SUBHEAD, type: 'website', siteName: SITE_NAME, url: '/', @@ -41,7 +48,7 @@ export const metadata: Metadata = { twitter: { card: 'summary_large_image', title: 'Agent UI for Angular', - description: 'Signal-native streaming for LangGraph — production patterns your Angular team can own.', + description: LONG_SUBHEAD, images: [DEFAULT_SOCIAL_IMAGE], }, }; diff --git a/apps/website/src/app/opengraph-image.tsx b/apps/website/src/app/opengraph-image.tsx index 47d7c538..76f7269b 100644 --- a/apps/website/src/app/opengraph-image.tsx +++ b/apps/website/src/app/opengraph-image.tsx @@ -6,10 +6,11 @@ * file in any route folder. */ import { ImageResponse } from 'next/og'; +import { POSITIONING_PROOF_POINTS, PRIMARY_TAGLINE, SHORT_POSITIONING_DESCRIPTION } from '../lib/positioning'; // Node runtime (not edge) so we can read the bundled Garamond TTF off disk. export const runtime = 'nodejs'; -export const alt = 'Agent UI for Angular — Signal-native streaming for Angular + LangGraph'; +export const alt = PRIMARY_TAGLINE; export const size = { width: 1200, height: 630 }; export const contentType = 'image/png'; @@ -127,8 +128,7 @@ export default async function OpenGraphImage() { marginBottom: 'auto', }} > - Build fullstack agentic Angular apps with signal-native streaming, - runtime adapters, generative UI, and production-ready primitives. + {SHORT_POSITIONING_DESCRIPTION}
{/* Footer row — pill trust signals + wordmark */} @@ -141,9 +141,11 @@ export default async function OpenGraphImage() { }} >
- MIT - LangGraph + AG-UI - Angular 20+ + {POSITIONING_PROOF_POINTS.slice(0, 3).map((proofPoint, index) => ( + + {proofPoint} + + ))}
- provideAgent + agent() give you signals for messages, status, errors, and interrupts. LangGraph and AG-UI adapters share the contract — swap runtimes without rewriting the UI. + provideAgent + agent() give you headless chat, durable threads, interrupts, tool progress, and generative UI. LangGraph and AG-UI adapters share the contract, so teams can swap runtimes without rewriting the Angular surface. } bullets={[ - 'Token-level streaming straight into Angular signals', - 'Thread state, interrupts, tool progress, branch/history', + 'Headless chat and durable thread state', + 'Interrupts, tool progress, branch/history', 'Adapters: LangGraph (@ngaf/langgraph), AG-UI (@ngaf/ag-ui)', - 'One contract, swappable runtimes', + 'One Angular UI layer, swappable runtimes', ]} supportingCards={[ { title: 'provideAgent', description: 'Wire the agent into your app.config.ts.' }, diff --git a/apps/website/src/components/landing/EcosystemStrip.tsx b/apps/website/src/components/landing/EcosystemStrip.tsx index 19466319..ddb1b384 100644 --- a/apps/website/src/components/landing/EcosystemStrip.tsx +++ b/apps/website/src/components/landing/EcosystemStrip.tsx @@ -144,7 +144,7 @@ export function EcosystemStrip() { margin: 0, }} > - NGAF gives Angular teams signal-native primitives for LangGraph, AG-UI, chat, and generative UI without locking the backend to one provider. + NGAF gives Angular teams production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI without locking the backend to one provider.

diff --git a/apps/website/src/components/landing/Hero.spec.tsx b/apps/website/src/components/landing/Hero.spec.tsx index 2a174705..2a18585d 100644 --- a/apps/website/src/components/landing/Hero.spec.tsx +++ b/apps/website/src/components/landing/Hero.spec.tsx @@ -3,6 +3,7 @@ import React from 'react'; import { describe, expect, it, vi, beforeEach } from 'vitest'; import { render, screen, fireEvent } from '@testing-library/react'; +import { HERO_SUBHEAD, POSITIONING_PROOF_POINTS } from '../../lib/positioning'; const trackMock = vi.hoisted(() => vi.fn()); const writeTextMock = vi.hoisted(() => vi.fn().mockResolvedValue(undefined)); @@ -50,7 +51,10 @@ describe('Hero', () => { render(); expect(screen.getByRole('heading', { level: 1 }).textContent) .toMatch(/Ship production agent UIs in Angular\./); - expect(screen.getByText(/Signal-native chat, threads, interrupts/)).toBeTruthy(); + expect(screen.getByText(HERO_SUBHEAD)).toBeTruthy(); + for (const proofPoint of POSITIONING_PROOF_POINTS) { + expect(screen.getByText(proofPoint)).toBeTruthy(); + } }); it('primary CTA copies the install command and fires cta_id=hero_install', async () => { diff --git a/apps/website/src/components/landing/Hero.tsx b/apps/website/src/components/landing/Hero.tsx index 216ea86c..155371a5 100644 --- a/apps/website/src/components/landing/Hero.tsx +++ b/apps/website/src/components/landing/Hero.tsx @@ -10,6 +10,7 @@ import { BrowserFrame } from '../ui/BrowserFrame'; import { Pill } from '../ui/Pill'; import { track } from '../../lib/analytics/client'; import { analyticsEvents } from '../../lib/analytics/events'; +import { HERO_SUBHEAD, POSITIONING_PROOF_POINTS } from '../../lib/positioning'; const INSTALL_COMMAND = 'npm install @ngaf/chat'; const COPY_FEEDBACK_MS = 1500; @@ -104,7 +105,7 @@ export function Hero() { maxWidth: '54ch', }} > - Signal-native chat, threads, interrupts, tool progress, and generative UI for LangGraph, AG-UI, and A2UI. MIT-licensed, self-hostable, app telemetry off by default, no React rewrite. + {HERO_SUBHEAD}

@@ -119,12 +120,11 @@ export function Hero() { marginBottom: 12, }} > - MIT - Angular-native Signals - LangGraph + AG-UI - A2UI-compatible - Self-hostable - App telemetry off by default + {POSITIONING_PROOF_POINTS.map((proofPoint, index) => ( + + {proofPoint} + + ))}

- The enterprise Angular agent framework for LangChain. Signal-native streaming built for production Angular 20+. + {SHORT_POSITIONING_DESCRIPTION}

{/* Social links */} diff --git a/apps/website/src/lib/docs-config.ts b/apps/website/src/lib/docs-config.ts index 04db8d8d..ac8e3e45 100644 --- a/apps/website/src/lib/docs-config.ts +++ b/apps/website/src/lib/docs-config.ts @@ -31,7 +31,7 @@ export const docsConfig: DocsLibrary[] = [ { id: 'agent', title: 'Agent', - description: 'Streaming state management for LangGraph agents', + description: 'Production agent state for Angular UI', sections: [ { title: 'Getting Started', diff --git a/apps/website/src/lib/docs.spec.ts b/apps/website/src/lib/docs.spec.ts index 288f5b6a..cd9a17a0 100644 --- a/apps/website/src/lib/docs.spec.ts +++ b/apps/website/src/lib/docs.spec.ts @@ -135,6 +135,7 @@ describe('website docs bindings', () => { '@ngaf/a2ui', '@ngaf/ag-ui', '@ngaf/chat', + '@ngaf/chat/debug', '@ngaf/chat/testing', '@ngaf/langgraph', '@ngaf/licensing', diff --git a/apps/website/src/lib/positioning.ts b/apps/website/src/lib/positioning.ts new file mode 100644 index 00000000..fc9750cf --- /dev/null +++ b/apps/website/src/lib/positioning.ts @@ -0,0 +1,13 @@ +export const PRIMARY_TAGLINE = 'Agent UI for Angular — Production-ready chat, threads, and generative UI for AI agents.'; +export const LONG_SUBHEAD = 'The enterprise-grade Angular UI framework for LangGraph and AG-UI-compatible agents: headless chat, durable threads, interrupts, subagents, planning, memory, and generative UI through json-render and A2UI-compatible specs.'; +export const HERO_SUBHEAD = 'Build enterprise-grade agent experiences in Angular: headless chat, durable threads, interrupts, subagents, planning, memory, and generative UI for LangGraph, AG-UI, json-render, and A2UI-compatible backends.'; +export const POSITIONING_PROOF_POINTS = [ + 'LangGraph + AG-UI', + 'Durable threads', + 'Interrupts', + 'Subagents', + 'Planning + memory', + 'json-render + A2UI', +] as const; +export const SHORT_POSITIONING_DESCRIPTION = 'Production-ready chat, durable threads, interrupts, subagents, planning, memory, and generative UI for Angular agent apps.'; +export const DEFAULT_META_DESCRIPTION = SHORT_POSITIONING_DESCRIPTION; diff --git a/apps/website/src/lib/site-metadata.spec.ts b/apps/website/src/lib/site-metadata.spec.ts new file mode 100644 index 00000000..990e52f5 --- /dev/null +++ b/apps/website/src/lib/site-metadata.spec.ts @@ -0,0 +1,43 @@ +import { describe, expect, it } from 'vitest'; +import { + DEFAULT_META_DESCRIPTION, + HERO_SUBHEAD, + LONG_SUBHEAD, + POSITIONING_PROOF_POINTS, + PRIMARY_TAGLINE, + SHORT_POSITIONING_DESCRIPTION, + createPageMetadata, +} from './site-metadata'; + +describe('site positioning copy', () => { + it('exports the approved primary tagline and supporting copy', () => { + expect(PRIMARY_TAGLINE).toBe('Agent UI for Angular — Production-ready chat, threads, and generative UI for AI agents.'); + expect(LONG_SUBHEAD).toContain('enterprise-grade Angular UI framework'); + expect(LONG_SUBHEAD).toContain('LangGraph and AG-UI-compatible agents'); + expect(LONG_SUBHEAD).toContain('json-render and A2UI-compatible specs'); + expect(HERO_SUBHEAD).toContain('headless chat, durable threads, interrupts, subagents, planning, memory'); + expect(POSITIONING_PROOF_POINTS).toEqual([ + 'LangGraph + AG-UI', + 'Durable threads', + 'Interrupts', + 'Subagents', + 'Planning + memory', + 'json-render + A2UI', + ]); + expect(DEFAULT_META_DESCRIPTION).toBe(SHORT_POSITIONING_DESCRIPTION); + }); + + it('uses canonical copy in generated page metadata', () => { + const metadata = createPageMetadata({ + title: PRIMARY_TAGLINE, + description: DEFAULT_META_DESCRIPTION, + pathname: '/', + type: 'website', + }); + + expect(metadata.title).toBe(PRIMARY_TAGLINE); + expect(metadata.description).toBe(DEFAULT_META_DESCRIPTION); + expect(metadata.openGraph?.description).toBe(DEFAULT_META_DESCRIPTION); + expect(metadata.twitter?.description).toBe(DEFAULT_META_DESCRIPTION); + }); +}); diff --git a/apps/website/src/lib/site-metadata.ts b/apps/website/src/lib/site-metadata.ts index bc34fa29..40412513 100644 --- a/apps/website/src/lib/site-metadata.ts +++ b/apps/website/src/lib/site-metadata.ts @@ -6,6 +6,14 @@ import { getAllPosts } from './blog'; export const SITE_ORIGIN = 'https://threadplane.ai'; export const SITE_NAME = 'Agent UI for Angular'; export const DEFAULT_SOCIAL_IMAGE = '/opengraph-image'; +export { + DEFAULT_META_DESCRIPTION, + HERO_SUBHEAD, + LONG_SUBHEAD, + POSITIONING_PROOF_POINTS, + PRIMARY_TAGLINE, + SHORT_POSITIONING_DESCRIPTION, +} from './positioning'; export function getCanonicalPath(pathname: string): string { if (pathname === '/') return '/'; diff --git a/apps/website/src/lib/solutions-data.ts b/apps/website/src/lib/solutions-data.ts index 1b301a6d..19f6abb1 100644 --- a/apps/website/src/lib/solutions-data.ts +++ b/apps/website/src/lib/solutions-data.ts @@ -64,7 +64,7 @@ export const SOLUTIONS: SolutionConfig[] = [ { library: 'Agent', pkg: '@ngaf/langgraph', - role: 'Signal-native streaming with first-class interrupt support. Every agent action can require human approval before execution. Thread persistence preserves the full record of every tool call and state transition.', + role: 'Production agent state with first-class interrupt support. Every agent action can require human approval before execution. Durable thread persistence preserves the full record of every tool call and state transition.', }, { library: 'Render', diff --git a/docs/gtm/icp.md b/docs/gtm/icp.md index 24964b60..12e52700 100644 --- a/docs/gtm/icp.md +++ b/docs/gtm/icp.md @@ -23,7 +23,8 @@ These are the signals to instrument first in Spec 1. Baseline rates between them - Angular Reddit, ng-conf community, Angular Discord/Slack equivalents, LangChain forum, AG-UI / A2UI communities, dev.to/medium. **What they need to see in 30 seconds** -- "Not another agent runtime. The Angular UI layer for LangGraph/AG-UI/A2UI." +- "Agent UI for Angular — Production-ready chat, threads, and generative UI for AI agents." +- `LangGraph + AG-UI · Durable threads · Interrupts · Subagents · Planning + memory · json-render + A2UI` - One install command. - A working demo they can clone. diff --git a/docs/gtm/messaging.md b/docs/gtm/messaging.md index 866ea5ab..e7b05859 100644 --- a/docs/gtm/messaging.md +++ b/docs/gtm/messaging.md @@ -4,21 +4,21 @@ ## Positioning statement (durable) -> For Angular teams building AI agents on LangGraph, AG-UI, or custom backends, ThreadPlane is the open-source agent UI framework that turns streaming agent events into production-grade Angular experiences: chat, tool progress, approvals, threads, generative UI, fallbacks, observability, and tests. Unlike React-first agent UI stacks or raw streaming SDKs, ThreadPlane is signal-native, DI-friendly, design-system-first, self-hostable, and built for enterprise Angular apps. +> For Angular teams building AI agents on LangGraph, AG-UI, or custom backends, ThreadPlane is the open-source agent UI framework that turns streaming agent events into production-ready Angular experiences: chat, durable threads, interrupts, subagents, planning, memory, generative UI, fallbacks, observability, and tests. Unlike React-first agent UI stacks or raw streaming SDKs, ThreadPlane is Angular-native, DI-friendly, design-system-first, self-hostable, and built for enterprise Angular apps. ## Hero (locked for Spec 2 to implement) **H1:** Ship production agent UIs in Angular. -**Subhead:** Signal-native chat, threads, interrupts, tool progress, and generative UI for LangGraph, AG-UI, and A2UI. MIT-licensed, self-hostable, app telemetry off by default, no React rewrite. +**Subhead:** Build enterprise-grade agent experiences in Angular: headless chat, durable threads, interrupts, subagents, planning, memory, and generative UI for LangGraph, AG-UI, json-render, and A2UI-compatible backends. **Primary CTA:** `Install @ngaf/chat` (copy-to-clipboard, fires `marketing:cta_click` with `cta_id=hero_install`, `track=developer`). **Secondary CTA:** `Talk to our engineers` (routes to `/contact?source=home_hero&track=enterprise`, fires `marketing:cta_click` with `cta_id=hero_talk_to_engineers`, `track=enterprise`). -**Proof row:** `MIT · Angular-native Signals · LangGraph + AG-UI · A2UI-compatible · Self-hostable · App telemetry off by default` +**Proof row:** `LangGraph + AG-UI · Durable threads · Interrupts · Subagents · Planning + memory · json-render + A2UI` -**Subline under proof row:** *Not another backend agent runtime. Keep LangGraph, Genkit, Mastra, CrewAI, or your own service. ThreadPlane solves the Angular UI layer.* +**Subline under proof row:** *Not another backend agent runtime. Keep LangGraph, Genkit, Mastra, CrewAI, or your own service. ThreadPlane solves the production Angular UI layer.* ## The five durable differentiation points @@ -64,7 +64,7 @@ Hidden attribution fields (populated by URL params + referrer): `source_page`, ` ## Launch narrative (Spec 6 spine) -> Angular teams are building agents, but the last mile is still messy: streaming state, tool progress, interrupts, threads, generated UI, fallbacks, and tests. React has mature examples. Backend agent frameworks have protocols. Angular teams need something that speaks Signals, DI, templates, standalone components, and enterprise design systems. ThreadPlane is an MIT-licensed agent UI framework for Angular that connects LangGraph, AG-UI, A2UI, and custom backends to production-ready Angular surfaces. +> Angular teams are building agents, but the last mile is still messy: streaming state, tool progress, interrupts, durable threads, subagents, planning, memory, generated UI, fallbacks, and tests. React has mature examples. Backend agent frameworks have protocols. Angular teams need something that speaks Signals, DI, templates, standalone components, and enterprise design systems. ThreadPlane is an MIT-licensed agent UI framework for Angular that connects LangGraph, AG-UI, A2UI, and custom backends to production-ready Angular surfaces. ## Avoid