1- import {
2- Component ,
3- effect ,
4- ElementRef ,
5- inject ,
6- viewChild ,
7- } from '@angular/core' ;
1+ import { Component , effect , ElementRef , inject , viewChild } from '@angular/core' ;
82import { MatProgressBarModule } from '@angular/material/progress-bar' ;
9- import { chatResource } from '@hashbrownai/angular' ;
3+ import { prompt , s } from '@hashbrownai/core' ;
4+ import { exposeComponent , RenderMessageComponent , uiChatResource } from '@hashbrownai/angular' ;
105import { SmartHome } from '../smart-home' ;
116import { Squircle } from '../squircle' ;
127import { ChatLayout } from './chat-layout' ;
138import { ChatPrompts } from './chat-prompts' ;
149import { Composer } from './composer' ;
10+ import { Markdown } from './markdown' ;
1511
1612@Component ( {
1713 selector : 'app-chat-panel' ,
1814 standalone : true ,
19- imports : [ MatProgressBarModule , Composer , ChatLayout , ChatPrompts , Squircle ] ,
15+ imports : [
16+ MatProgressBarModule ,
17+ Composer ,
18+ ChatLayout ,
19+ ChatPrompts ,
20+ Squircle ,
21+ RenderMessageComponent ,
22+ ] ,
2023 template : `
2124 <div
2225 class="container"
@@ -25,18 +28,24 @@ import { Composer } from './composer';
2528 appSquircleBorderColor="#EEC7AD"
2629 >
2730 @if (chat.isLoading()) {
28- <div class="chat-loading">
29- <mat-progress-bar mode="indeterminate"></mat-progress-bar>
30- </div>
31+ <div class="chat-loading">
32+ <mat-progress-bar mode="indeterminate"></mat-progress-bar>
33+ </div>
3134 }
3235 <app-chat-layout>
3336 <div class="chat-messages" #contentDiv>
3437 @for (message of chat.value(); track $index) {
35- <div class="chat-message">
36- <p>{{ message.content }}</p>
37- </div>
38- } @if (chat.value().length === 0) {
39- <app-chat-prompts (selectPrompt)="sendMessage($event)" />
38+ @switch (message.role) {
39+ @case ('user') {
40+ <p>{{ message.content }}</p>
41+ }
42+ @case ('assistant') {
43+ <hb-render-message [message]="message" />
44+ }
45+ }
46+ }
47+ @if (chat.value().length === 0) {
48+ <app-chat-prompts (selectPrompt)="sendMessage($event)" />
4049 }
4150 </div>
4251 <app-chat-composer
@@ -102,11 +111,41 @@ export class ChatPanelComponent {
102111 } ) ;
103112 }
104113
105- chat = chatResource ( {
114+ chat = uiChatResource ( {
106115 model : 'gpt-4.1' ,
107- debugName : 'chatResource' ,
108- system :
109- 'You are a helpful assistant that can answer questions and help with tasks.' ,
116+ debugName : 'ui-chat' ,
117+ system : prompt `
118+ ### ROLE & TONE
119+ You are **Smart Home Assistant**, a friendly and concise AI assistant for a
120+ smart home web application.
121+
122+ - Voice: clear, helpful, and respectful.
123+ - Audience: users controlling lights and scenes via the web interface.
124+
125+ ### RULES
126+ 1. **Never** expose raw data or internal code details.
127+ 2. For commands you cannot perform, **admit it** and suggest an alternative.
128+ 3. For actionable requests (e.g., changing light settings), **precede** any
129+ explanation with the appropriate tool call.
130+
131+
132+ ### EXAMPLES
133+
134+ <user>Hello</user>
135+ <assistant>
136+ <ui>
137+ <app-markdown data="How may I assist you?" />
138+ </ui>
139+ </assistant>
140+ ` ,
141+ components : [
142+ exposeComponent ( Markdown , {
143+ description : 'Show markdown to the user' ,
144+ input : {
145+ data : s . streaming . string ( 'The markdown content' ) ,
146+ } ,
147+ } ) ,
148+ ] ,
110149 } ) ;
111150
112151 sendMessage ( message : string ) {
0 commit comments