11"use client"
22
33import React , { useEffect } from "react"
4- import type { Message as SDKMessage } from "ai"
4+ import type { UIMessage as SDKMessage } from "ai"
55import { cva , type VariantProps } from "class-variance-authority"
66import { MarkdownRenderer } from "./markdown-renderer"
77import { cn } from "utils/cn"
@@ -13,6 +13,17 @@ import { useCartStore } from "stores/cart-store"
1313import { CreditCard , SearchCheck , ShoppingCart } from "lucide-react"
1414import { useToolInvocationStore } from "stores/tool-invocation-store"
1515
16+ type Part = SDKMessage [ "parts" ] [ number ]
17+ type ToolPart = Part & { toolName : string ; toolCallId : string ; state : string ; output ?: unknown }
18+
19+ function isToolPart ( part : Part ) : part is ToolPart {
20+ return part . type === "dynamic-tool" || part . type . startsWith ( "tool-" )
21+ }
22+
23+ function getTextFromParts ( parts : Part [ ] ) : string {
24+ return parts . filter ( ( p ) => p . type === "text" ) . map ( ( p ) => ( p as { text : string } ) . text ) . join ( "" )
25+ }
26+
1627const chatBubbleVariants = cva ( "group/message relative break-words rounded-lg text-sm sm:max-w-[70%]" , {
1728 variants : {
1829 role : {
@@ -57,8 +68,6 @@ const chatBubbleVariants = cva("group/message relative break-words rounded-lg te
5768type Animation = VariantProps < typeof chatBubbleVariants > [ "animation" ]
5869
5970export interface Message extends SDKMessage {
60- id : string
61- content : string
6271 createdAt ?: Date
6372}
6473
@@ -71,11 +80,10 @@ export interface ChatMessageProps extends Message {
7180
7281export const ChatMessage : React . FC < ChatMessageProps > = ( {
7382 role,
74- content ,
83+ parts ,
7584 createdAt,
7685 showTimeStamp = false ,
7786 animation = "scale" ,
78- toolInvocations,
7987 showToolMessages,
8088 actions,
8189} ) => {
@@ -86,33 +94,36 @@ export const ChatMessage: React.FC<ChatMessageProps> = ({
8694 minute : "2-digit" ,
8795 } )
8896
89- if ( toolInvocations ?. length ) {
90- return toolInvocations . map ( ( toolInvocation ) => {
91- const { toolName, toolCallId, state } = toolInvocation
97+ const toolParts = parts . filter ( isToolPart )
98+
99+ if ( toolParts . length ) {
100+ return toolParts . map ( ( toolPart ) => {
101+ const { toolName, toolCallId, state } = toolPart as { toolName : string ; toolCallId : string ; state : string ; output ?: unknown }
102+
103+ if ( state === "output-available" ) {
104+ const output = ( toolPart as { output : unknown } ) . output
92105
93- if ( state === "result" ) {
94106 if ( toolName === "navigateUser" ) {
95- const { result } = toolInvocation
96- return < NavigationToolResult key = { toolCallId } result = { result } animation = { animation } toolCallId = { toolCallId } />
107+ return < NavigationToolResult key = { toolCallId } result = { output as string } animation = { animation } toolCallId = { toolCallId } />
97108 }
98109 if ( toolName === "addToCart" ) {
99- const { result } = toolInvocation
110+ const { variant , product } = output as { variant : unknown ; product : unknown }
100111 return (
101112 < AddedToCart
102113 key = { toolCallId }
103- variant = { result . variant }
104- product = { result . product }
114+ variant = { variant }
115+ product = { product }
105116 animation = { animation }
106117 toolCallId = { toolCallId }
107118 />
108119 )
109120 }
110121 if ( toolName === "goToCheckout" ) {
111- const { result } = toolInvocation
122+ const { checkoutUrl } = output as { checkoutUrl : string }
112123 return (
113124 < MoveToCheckout
114125 key = { toolCallId }
115- checkoutUrl = { result . checkoutUrl }
126+ checkoutUrl = { checkoutUrl }
116127 animation = { animation }
117128 toolCallId = { toolCallId }
118129 />
@@ -123,6 +134,8 @@ export const ChatMessage: React.FC<ChatMessageProps> = ({
123134 } )
124135 }
125136
137+ const content = getTextFromParts ( parts )
138+
126139 return (
127140 < motion . div
128141 initial = { { opacity : 0 , y : 5 } }
0 commit comments