Skip to content

Commit d2cdcfb

Browse files
authored
[ch-chat] Move the header of chat messages to the contentBefore section (#669)
This allows the users to more easily add custom content in between the header and the message content
1 parent 606a015 commit d2cdcfb

File tree

1 file changed

+53
-53
lines changed

1 file changed

+53
-53
lines changed

packages/mercury/src/components/chat/render.lit.ts

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ The chat styles are designed for a specific layout, so users must use the sendCo
2424
*/
2525

2626
import { html, nothing, type TemplateResult } from "lit";
27-
import type { MercuryChatMessageMetadata } from "./types";
2827

2928
import type {
3029
ChatActionsRender,
@@ -58,13 +57,14 @@ import "./mer-animated-dots.js";
5857
* @param messageMetaData - Metadata containing agentName and time
5958
* @returns TemplateResult rendering the assistant message header
6059
*/
61-
const messageHeader = (
62-
messageMetaData: MercuryChatMessageMetadata | undefined,
63-
waiting: boolean = false
64-
): TemplateResult => {
65-
const agentName = messageMetaData?.agentName;
60+
const messageHeader = (message: ChatMessage): TemplateResult => {
61+
if (message.role === "system" || message.role === "user") {
62+
return nothing as never; // TODO: Improve type safety in the ch-chat (nicolas-camera_globant)
63+
}
64+
65+
const agentName = message.metadata?.agentName;
6666
const assistantId = agentName?.toLowerCase().replace(/ /g, "-");
67-
const messageTime = messageMetaData?.time;
67+
const messageTime = message.metadata?.time;
6868

6969
return html`<div
7070
part="header assistant${assistantId ? ` header-${assistantId}` : ""}"
@@ -75,7 +75,9 @@ const messageHeader = (
7575
<div part="header__avatar-image assistant"></div>
7676
</div>
7777
<div part="header__role assistant">${agentName}</div>
78-
${waiting ? html`<mer-animated-dots></mer-animated-dots>` : nothing}
78+
${message.role === "assistant" && message.status === "waiting"
79+
? html`<mer-animated-dots></mer-animated-dots>`
80+
: nothing}
7981
</div>
8082
8183
${messageTime
@@ -95,59 +97,56 @@ const customAssistantContentRender = (
9597
const messageContent = getMessageContent(message);
9698

9799
return message.status === "waiting"
98-
? html`${messageHeader(message.metadata, true)}
99-
<div
100-
class="assistant-loading"
101-
part=${tokenMap({
102-
[`assistant content waiting ${message.id}`]: true,
103-
...(message.parts ? { [message.parts]: true } : {})
104-
})}
105-
>
106-
${messageContent}
107-
</div>`
108-
: html`${messageHeader(message.metadata)}
109-
<ch-markdown-viewer
110-
part=${tokenMap({
111-
[`assistant content ${message.id} ${
112-
message.status ?? DEFAULT_ASSISTANT_STATUS
113-
}`]: true,
114-
...(message.parts ? { [message.parts]: true } : {})
115-
})}
116-
.renderCode=${
117-
// WA: Define codeBlockRender as "never" to avoid types incompatibility:
118-
// codeBlockRender returns TemplateResult and renderCode expects TemplateResult | undefined
119-
// In Chameleon this type mismatch does not happens. TODO: Evaluate a solution in Chameleon.
120-
codeBlockRender(chatRef) as never
121-
}
122-
.showIndicator=${message.status === "streaming"}
123-
.theme=${chatRef.markdownTheme ?? undefined}
124-
.value=${messageContent}
125-
></ch-markdown-viewer>`;
100+
? html`<div
101+
class="assistant-loading"
102+
part=${tokenMap({
103+
[`assistant content waiting ${message.id}`]: true,
104+
...(message.parts ? { [message.parts]: true } : {})
105+
})}
106+
>
107+
${messageContent}
108+
</div>`
109+
: html`<ch-markdown-viewer
110+
part=${tokenMap({
111+
[`assistant content ${message.id} ${
112+
message.status ?? DEFAULT_ASSISTANT_STATUS
113+
}`]: true,
114+
...(message.parts ? { [message.parts]: true } : {})
115+
})}
116+
.renderCode=${
117+
// WA: Define codeBlockRender as "never" to avoid types incompatibility:
118+
// codeBlockRender returns TemplateResult and renderCode expects TemplateResult | undefined
119+
// In Chameleon this type mismatch does not happens. TODO: Evaluate a solution in Chameleon.
120+
codeBlockRender(chatRef) as never
121+
}
122+
.showIndicator=${message.status === "streaming"}
123+
.theme=${chatRef.markdownTheme ?? undefined}
124+
.value=${messageContent}
125+
></ch-markdown-viewer>`;
126126
};
127127

128-
// customzied in order to add the custom "messageHeader"
128+
// Customized in order to add the custom "messageHeader"
129129
const customErrorContentRender = (
130130
message: ChatMessageByRole<"error">,
131131
chatRef: HTMLChChatElement,
132132
codeBlockRender: ChatCodeBlockRender
133133
) => {
134134
const errorContent = getMessageContent(message);
135135

136-
return html`${messageHeader(message.metadata)}
137-
<ch-markdown-viewer
138-
part=${tokenMap({
139-
[`error content ${message.id}`]: true,
140-
...(message.parts ? { [message.parts]: true } : {})
141-
})}
142-
.renderCode=${
143-
// WA: Define codeBlockRender as "never" to avoid types incompatibility:
144-
// codeBlockRender returns TemplateResult and renderCode expects TemplateResult | undefined
145-
// In Chameleon this type mismatch does not happens. TODO: Evaluate a solution in Chameleon.
146-
codeBlockRender(chatRef) as never
147-
}
148-
.theme=${chatRef.markdownTheme ?? undefined}
149-
.value=${errorContent}
150-
></ch-markdown-viewer>`;
136+
return html`<ch-markdown-viewer
137+
part=${tokenMap({
138+
[`error content ${message.id}`]: true,
139+
...(message.parts ? { [message.parts]: true } : {})
140+
})}
141+
.renderCode=${
142+
// WA: Define codeBlockRender as "never" to avoid types incompatibility:
143+
// codeBlockRender returns TemplateResult and renderCode expects TemplateResult | undefined
144+
// In Chameleon this type mismatch does not happens. TODO: Evaluate a solution in Chameleon.
145+
codeBlockRender(chatRef) as never
146+
}
147+
.theme=${chatRef.markdownTheme ?? undefined}
148+
.value=${errorContent}
149+
></ch-markdown-viewer>`;
151150
};
152151

153152
// No modification. It is required to be defined.
@@ -181,8 +180,9 @@ const customContentRender: ChatContentRender = (
181180
) =>
182181
contentRenderByRole[message.role](message as never, chatRef, codeBlockRender);
183182

184-
export const renderItem: ChatMessageRenderBySections = {
183+
export const renderItem = {
185184
actions: customActionsRender,
185+
contentBefore: messageHeader,
186186
codeBlock: customCodeBlockRender,
187187
content: customContentRender,
188188
file: customFileRenders

0 commit comments

Comments
 (0)