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
12 changes: 12 additions & 0 deletions apps/website/content/docs/chat/api/api-docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -1747,6 +1747,12 @@
"type": "InputSignal<string | null>",
"description": "Keyboard shortcut (single key) that toggles the popup with cmd (mac)\nor ctrl (other). Set to `null` to disable. Default: 'k' — matches the\nwidely-used cmd/ctrl+K convention.",
"optional": false
},
{
"name": "views",
"type": "InputSignal<Readonly<Record<string, Type<unknown>>> | undefined>",
"description": "A2UI component catalog forwarded to the inner <chat>. Without it,\nmessages classified as A2UI parse correctly but never mount a\nsurface. Pass `a2uiBasicCatalog()` from `@ngaf/chat`.",
"optional": false
}
],
"methods": [
Expand Down Expand Up @@ -1963,6 +1969,12 @@
"type": "InputSignal<boolean>",
"description": "",
"optional": false
},
{
"name": "views",
"type": "InputSignal<Readonly<Record<string, Type<unknown>>> | undefined>",
"description": "A2UI component catalog forwarded to the inner <chat>. Without it,\nmessages classified as A2UI parse correctly but never mount a\nsurface. Pass `a2uiBasicCatalog()` from `@ngaf/chat`.",
"optional": false
}
],
"methods": [
Expand Down
9 changes: 7 additions & 2 deletions examples/chat/angular/src/app/modes/embed-mode.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { ChatComponent, ChatWelcomeSuggestionComponent } from '@ngaf/chat';
import { ChatComponent, ChatWelcomeSuggestionComponent, a2uiBasicCatalog } from '@ngaf/chat';
import { DEMO_AGENT } from '../shell/shell-tokens';
import { WELCOME_SUGGESTIONS } from './welcome-suggestions';

Expand All @@ -10,7 +10,7 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
imports: [ChatComponent, ChatWelcomeSuggestionComponent],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<chat [agent]="agent">
<chat [agent]="agent" [views]="catalog">
<div chatWelcomeSuggestions>
@for (s of suggestions; track s.value) {
<chat-welcome-suggestion
Expand All @@ -29,6 +29,11 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
export class EmbedMode {
protected readonly agent = inject(DEMO_AGENT);
protected readonly suggestions = WELCOME_SUGGESTIONS;
// Phase 4: catalog of A2UI components the chat composition uses to
// render <a2ui-surface> when an AI message content begins with the
// ---a2ui_JSON--- wire-format prefix. Without this, the surface is
// parsed correctly but never mounted (the @if gate requires views()).
protected readonly catalog = a2uiBasicCatalog();

protected send(text: string): void {
void this.agent.submit({ message: text });
Expand Down
6 changes: 4 additions & 2 deletions examples/chat/angular/src/app/modes/popup-mode.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { ChatPopupComponent, ChatWelcomeSuggestionComponent } from '@ngaf/chat';
import { ChatPopupComponent, ChatWelcomeSuggestionComponent, a2uiBasicCatalog } from '@ngaf/chat';
import { DEMO_AGENT } from '../shell/shell-tokens';
import { WELCOME_SUGGESTIONS } from './welcome-suggestions';

Expand All @@ -15,7 +15,7 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
Click the launcher button (bottom-right) to open the chat.
</p>
</div>
<chat-popup [agent]="agent">
<chat-popup [agent]="agent" [views]="catalog">
<div chatWelcomeSuggestions>
@for (s of suggestions; track s.value) {
<chat-welcome-suggestion
Expand All @@ -41,6 +41,8 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
export class PopupMode {
protected readonly agent = inject(DEMO_AGENT);
protected readonly suggestions = WELCOME_SUGGESTIONS;
// Phase 4: A2UI component catalog forwarded to <chat-popup>.
protected readonly catalog = a2uiBasicCatalog();

protected send(text: string): void {
void this.agent.submit({ message: text });
Expand Down
6 changes: 4 additions & 2 deletions examples/chat/angular/src/app/modes/sidebar-mode.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: MIT
import { Component, ChangeDetectionStrategy, inject } from '@angular/core';
import { ChatSidebarComponent, ChatWelcomeSuggestionComponent } from '@ngaf/chat';
import { ChatSidebarComponent, ChatWelcomeSuggestionComponent, a2uiBasicCatalog } from '@ngaf/chat';
import { DEMO_AGENT } from '../shell/shell-tokens';
import { WELCOME_SUGGESTIONS } from './welcome-suggestions';

Expand All @@ -15,7 +15,7 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
Click the launcher button (right edge) to slide in the chat panel.
</p>
</div>
<chat-sidebar [agent]="agent">
<chat-sidebar [agent]="agent" [views]="catalog">
<div chatWelcomeSuggestions>
@for (s of suggestions; track s.value) {
<chat-welcome-suggestion
Expand All @@ -41,6 +41,8 @@ import { WELCOME_SUGGESTIONS } from './welcome-suggestions';
export class SidebarMode {
protected readonly agent = inject(DEMO_AGENT);
protected readonly suggestions = WELCOME_SUGGESTIONS;
// Phase 4: A2UI component catalog forwarded to <chat-sidebar>.
protected readonly catalog = a2uiBasicCatalog();

protected send(text: string): void {
void this.agent.submit({ message: text });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
import { Component, ChangeDetectionStrategy, input, model, DestroyRef, inject, DOCUMENT, effect } from '@angular/core';
import type { Agent } from '../../agent';
import type { ViewRegistry } from '@ngaf/render';
import { ChatComponent } from '../chat/chat.component';
import { ChatLauncherButtonComponent } from '../../primitives/chat-launcher-button/chat-launcher-button.component';
import { CHAT_HOST_TOKENS } from '../../styles/chat-tokens';
Expand Down Expand Up @@ -63,14 +64,18 @@ import { CHAT_HOST_TOKENS } from '../../styles/chat-tokens';
<button type="button" class="chat-popup__close" (click)="closeWindow()" aria-label="Close chat">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
<chat [agent]="agent()">
<chat [agent]="agent()" [views]="views()">
<ng-content select="[chatHeader]" chatHeader />
</chat>
</div>
`,
})
export class ChatPopupComponent {
readonly agent = input.required<Agent>();
/** A2UI component catalog forwarded to the inner <chat>. Without it,
* messages classified as A2UI parse correctly but never mount a
* surface. Pass `a2uiBasicCatalog()` from `@ngaf/chat`. */
readonly views = input<ViewRegistry | undefined>(undefined);
readonly open = model(false);
/**
* Keyboard shortcut (single key) that toggles the popup with cmd (mac)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: MIT
import { Component, ChangeDetectionStrategy, input, model } from '@angular/core';
import type { Agent } from '../../agent';
import type { ViewRegistry } from '@ngaf/render';
import { ChatComponent } from '../chat/chat.component';
import { CHAT_HOST_TOKENS } from '../../styles/chat-tokens';

Expand Down Expand Up @@ -56,14 +57,18 @@ import { CHAT_HOST_TOKENS } from '../../styles/chat-tokens';
<button type="button" class="chat-sidebar__close" (click)="closeWindow()" aria-label="Close chat">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
<chat [agent]="agent()">
<chat [agent]="agent()" [views]="views()">
<ng-content select="[chatHeader]" chatHeader />
</chat>
</aside>
`,
})
export class ChatSidebarComponent {
readonly agent = input.required<Agent>();
/** A2UI component catalog forwarded to the inner <chat>. Without it,
* messages classified as A2UI parse correctly but never mount a
* surface. Pass `a2uiBasicCatalog()` from `@ngaf/chat`. */
readonly views = input<ViewRegistry | undefined>(undefined);
readonly open = model(false);
readonly pushContent = input<boolean>(false);

Expand Down
Loading