Skip to content

Commit f17f456

Browse files
bloveclaude
andauthored
feat(chat)!: remove provideChat(), fix app-level markdown registry overrides, and three API cleanups (#1055)
* feat(chat)!: remove provideChat(), ChatConfig, and CHAT_CONFIG No component in @threadplane/chat ever injected CHAT_CONFIG, so provideChat({}) configured nothing: renderRegistry, avatarLabel, and assistantName were values only a consumer's own wrappers could read back. The provider, the token, the interface, and the dead ChatConfig duplicate in chat.types.ts are deleted outright. Every call site follows: 35 cockpit example app.config.ts files, both standalone example apps, the chat and langgraph READMEs, the @threadplane /render JSDoc that referenced it, the docs pages that described it, and the blog tutorials whose bootstrap snippets would otherwise no longer compile. The three pages that documented the API — chat/api/provide-chat, chat/api/chat-config, and chat/guides/configuration — are deleted, dropped from the docs nav, added to the retired-route pattern the public-copy contract enforces, and permanently redirected (with their /api/markdown mirrors) to chat installation so delivered links do not 404. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(chat): let an ancestor MARKDOWN_VIEW_REGISTRY override markdown views <chat-streaming-md> provided MARKDOWN_VIEW_REGISTRY on its own component injector from its own default, so a provider at the application root or on a route was always shadowed and never reached the markdown node components. The [viewRegistry] input was the only override that worked. Resolution is now most-specific-first: the [viewRegistry] input, then a registry found through skipSelf on an ancestor injector, then cacheplaneMarkdownViews. The resolved value is still provided on the component injector, so <chat-md-children> and the table-row view are unchanged, and <chat> needs to forward nothing for an app-wide override to reach the markdown it renders for assistant messages. The new spec fails on the old resolution in two of its four cases (ancestor provider, and the same through <chat>) and passes on the other two, which pin the default and the input precedence. Restores an accurate "App-wide override" section in the markdown guide, which previously carried a Callout asserting the opposite, and corrects the CHANGELOG entry that made the same claim. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * refactor(chat): drop the unreachable 'mixed' content type, widen messageContent, tokenize the popup launcher Three small cleanups: - ContentType no longer carries 'mixed'. createContentClassifier never emitted it, so the `|| currentType === 'mixed'` branch in the delta path was dead and any consumer switch on it had a case no input reaches. The docs said as much and told readers not to branch on it; the member is simply gone instead. - messageContent() takes { content: unknown } rather than LangChain's BaseMessage. Every caller in this library holds the runtime-neutral Message from agent.messages(), so ChatComponent.humanContent carried a cast and the docs told consumers to pass something other than the message they actually have. The function reads nothing but .content, so the structural parameter is the honest signature; the cast is gone. - --tplane-chat-launcher-offset-x / -y (both 1rem) position the <chat-popup> launcher, which was pinned with hard-coded corner offsets. The popup window reads the horizontal one too, so it stays aligned when the launcher moves clear of a bottom bar or a consent banner. The new message-utils spec fails to type-check against the old BaseMessage signature (four errors under tsconfig.spec.json) and passes after. The new chat-popup styles spec fails four of its five cases before the change, and its window-alignment guard was mutation-checked by reverting that one declaration. Regenerates the chat and render api-docs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * fix(chat): drop the now-unused @langchain/core peer dependency Widening messageContent() to { content: unknown } removed the last LangChain import from the published package, so @nx/dependency-checks fails the declared peer. It stays a peer of @threadplane/langgraph, which is why the install command still lists it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
1 parent 8ae6a86 commit f17f456

121 files changed

Lines changed: 554 additions & 840 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

apps/website/content/blog/2026-05-17-build-a-streaming-chat-ui-in-angular-with-langgraph.mdx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,17 +95,15 @@ yarn add @threadplane/chat @threadplane/langgraph marked
9595
// app.config.ts
9696
import { ApplicationConfig } from '@angular/core';
9797
import { provideAgent } from '@threadplane/langgraph';
98-
import { provideChat } from '@threadplane/chat';
9998

10099
export const appConfig: ApplicationConfig = {
101100
providers: [
102101
provideAgent({ apiUrl: 'http://localhost:2024' }),
103-
provideChat({ assistantName: 'Assistant' }),
104102
],
105103
};
106104
```
107105

108-
`provideAgent` is the transport. `provideChat` is the UI configuration. They are independent on purpose — you can use one without the other.
106+
`provideAgent` is the transport, and it is the only provider the chat components need. The UI is configured entirely through component inputs, so the two layers stay independent on purpose.
109107

110108
</Step>
111109
<Step title="Create the agent in your component">

apps/website/content/blog/2026-05-21-build-fullstack-agentic-angular-apps-using-ag-ui.mdx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -115,21 +115,19 @@ It is a peer dep so you can swap it.
115115
// app.config.ts
116116
import { ApplicationConfig } from '@angular/core';
117117
import { provideAgent } from '@threadplane/ag-ui';
118-
import { provideChat } from '@threadplane/chat';
119118

120119
export const appConfig: ApplicationConfig = {
121120
providers: [
122121
provideAgent({ url: 'http://localhost:8000/agent' }),
123-
provideChat({ assistantName: 'Astra' }),
124122
],
125123
};
126124
```
127125

128126
That is the whole bootstrap.
129127
`provideAgent` is the AG-UI transport. It wraps the official `@ag-ui/client` `HttpAgent` and exposes the signal-shaped contract via DI.
130-
`provideChat` is the chat UI's configuration.
128+
It is the only provider the chat components need.
131129

132-
Notice they are independent.
130+
Notice how little the two layers know about each other.
133131
`@threadplane/chat` does not know it is talking to an AG-UI backend.
134132
It just reads from the `Agent` contract.
135133
We will lean on that boundary later.

apps/website/content/blog/2026-05-28-human-in-the-loop-langgraph-agents-in-angular.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,12 +117,10 @@ That is why `request_approval` can branch on `decision["approved"]` and pick up
117117
```ts
118118
// app.config.ts
119119
import { provideAgent } from '@threadplane/langgraph';
120-
import { provideChat } from '@threadplane/chat';
121120

122121
export const appConfig: ApplicationConfig = {
123122
providers: [
124123
provideAgent({ apiUrl: environment.langGraphApiUrl }),
125-
provideChat({}),
126124
],
127125
};
128126
```

apps/website/content/blog/2026-06-04-human-in-the-loop-ag-ui-agents-in-angular.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,12 +205,10 @@ Two details worth knowing:
205205
// app.config.ts — cockpit/ag-ui/interrupts/angular/src/app/app.config.ts
206206
import { ApplicationConfig } from '@angular/core';
207207
import { provideAgent } from '@threadplane/ag-ui';
208-
import { provideChat } from '@threadplane/chat';
209208

210209
export const appConfig: ApplicationConfig = {
211210
providers: [
212211
provideAgent({ url: '/agent' }),
213-
provideChat({}),
214212
],
215213
};
216214
```

apps/website/content/blog/2026-08-09-build-an-aws-strands-agent-ui-in-angular-with-ag-ui.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,14 +230,12 @@ Wire both packages into `app.config.ts`:
230230
```ts
231231
import { ApplicationConfig } from '@angular/core';
232232
import { provideAgent } from '@threadplane/ag-ui';
233-
import { provideChat } from '@threadplane/chat';
234233

235234
export const appConfig: ApplicationConfig = {
236235
providers: [
237236
provideAgent({
238237
url: 'http://localhost:8080/invocations',
239238
}),
240-
provideChat({ assistantName: 'Strands Assistant' }),
241239
],
242240
};
243241
```

apps/website/content/blog/2026-08-13-angular-chat-app-tutorial-with-ag-ui.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,14 +167,12 @@ npm install @threadplane/chat @threadplane/ag-ui @ag-ui/client @ag-ui/core marke
167167
The provider is one line, because AG-UI's connection surface is one URL:
168168

169169
```ts
170-
import { provideChat } from '@threadplane/chat';
171170
import { provideAgent } from '@threadplane/ag-ui';
172171

173172
export const appConfig: ApplicationConfig = {
174173
providers: [
175174
provideRouter(routes),
176175
provideAgent({ url: 'http://localhost:8000/agent' }),
177-
provideChat({ assistantName: 'Librarian' }),
178176
],
179177
};
180178
```

apps/website/content/blog/2026-08-13-angular-chat-app-tutorial-with-langchain-langgraph.mdx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,6 @@ import {
173173
signal,
174174
} from '@angular/core';
175175
import { provideRouter } from '@angular/router';
176-
import { provideChat } from '@threadplane/chat';
177176
import { LANGGRAPH_THREADS_CONFIG, provideAgent } from '@threadplane/langgraph';
178177

179178
import { routes } from './app.routes';
@@ -195,7 +194,6 @@ export const appConfig: ApplicationConfig = {
195194
onThreadId: (id) => ACTIVE_THREAD.set(id),
196195
}),
197196
{ provide: LANGGRAPH_THREADS_CONFIG, useValue: { apiUrl: API_URL } },
198-
provideChat({ assistantName: 'Assistant' }),
199197
],
200198
};
201199
```

apps/website/content/docs/a2ui/getting-started/introduction.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ Nothing in this file is specific to A2UI; the surfaces travel as assistant messa
9494

9595
<ExampleCode file="app.config.ts" title="app.config.ts" />
9696

97-
`provideChat({})` registers the chat composition defaults alongside it.
9897

9998
### Giving the chat composition a catalog
10099

apps/website/content/docs/ag-ui/guides/client-tools.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ The server is a FastAPI application. `LangGraphAgent` wraps the compiled graph a
3636

3737
### Providing the agent
3838

39-
`provideAgent()` from `@threadplane/ag-ui` registers the agent at the application root, and `provideChat({})` registers the chat defaults. The example resolves its URL at runtime because the host that serves the demo decides which runtime is attached; your own application passes a `url` directly.
39+
`provideAgent()` from `@threadplane/ag-ui` registers the agent at the application root, and it is the only provider the `<chat>` composition requires. The example resolves its URL at runtime because the host that serves the demo decides which runtime is attached; your own application passes a `url` directly.
4040

4141
<ExampleCode file="app.config.ts" />
4242

apps/website/content/docs/ag-ui/guides/interrupts.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ That wrapper is what turns a LangGraph pause into the AG-UI event described belo
7272

7373
### The agent provider
7474

75-
`provideAgent()` registers the agent once for the whole application, and `provideChat({})` registers the configuration the `<chat>` composition reads, here left at its defaults. The example passes a factory because it resolves its endpoint at runtime from the host that serves the demo.
75+
`provideAgent()` registers the agent once for the whole application, and it is the only provider the `<chat>` composition requires. The example passes a factory because it resolves its endpoint at runtime from the host that serves the demo.
7676

7777
<ExampleCode file="app.config.ts" />
7878

0 commit comments

Comments
 (0)