@@ -6,6 +6,16 @@ import {
6
6
AssistantRuntimeProvider ,
7
7
} from "@assistant-ui/react" ;
8
8
9
+ // Define your custom message type
10
+ interface MyMessage {
11
+ id : string ;
12
+ role : "user" | "assistant" ;
13
+ text : string ;
14
+ timestamp : number ;
15
+ }
16
+
17
+ const generateId = ( ) => Math . random ( ) . toString ( 36 ) . substr ( 2 , 9 ) ;
18
+
9
19
const callYourAPI = async ( message : AppendMessage ) => {
10
20
// Simulate API delay
11
21
await new Promise ( resolve => setTimeout ( resolve , 1500 ) ) ;
@@ -15,56 +25,120 @@ const callYourAPI = async (message: AppendMessage) => {
15
25
content : "This is a mock response from your backend. You typed: " +
16
26
( typeof message . content === 'string' ? message . content : 'something' )
17
27
} ;
18
- } ;
28
+ } ;
19
29
20
30
export function MyRuntimeProvider ( { children } : { children : React . ReactNode } ) {
21
- const [ messages , setMessages ] = useState < ThreadMessageLike [ ] > ( [ ] ) ;
31
+ // Use your custom message type in state
32
+ const [ myMessages , setMyMessages ] = useState < MyMessage [ ] > ( [ ] ) ;
22
33
const [ isRunning , setIsRunning ] = useState ( false ) ;
34
+
35
+ // Convert your custom format to ThreadMessageLike
36
+ const convertMessage = ( message : MyMessage ) : ThreadMessageLike => ( {
37
+ role : message . role ,
38
+ content : [ { type : "text" , text : message . text } ] ,
39
+ id : message . id ,
40
+ createdAt : new Date ( message . timestamp ) ,
41
+ } ) ;
23
42
24
43
const onNew = async ( message : AppendMessage ) => {
25
- // Add user message
26
- const userMessage : ThreadMessageLike = {
44
+ // Add user message in your custom format
45
+ const userMessage : MyMessage = {
46
+ id : generateId ( ) ,
27
47
role : "user" ,
28
- content : message . content ,
48
+ text : typeof message . content === 'string' ? message . content : JSON . stringify ( message . content ) ,
49
+ timestamp : Date . now ( ) ,
29
50
} ;
30
51
31
- setMessages ( prev => [ ...prev , userMessage ] ) ;
52
+ setMyMessages ( prev => [ ...prev , userMessage ] ) ;
32
53
setIsRunning ( true ) ;
33
54
34
55
try {
35
56
// Call mock API
36
57
const response = await callYourAPI ( message ) ;
37
58
38
- const assistantMessage : ThreadMessageLike = {
59
+ const assistantMessage : MyMessage = {
60
+ id : generateId ( ) ,
61
+ role : "assistant" ,
62
+ text : response . content ,
63
+ timestamp : Date . now ( ) ,
64
+ } ;
65
+
66
+ setMyMessages ( prev => [ ...prev , assistantMessage ] ) ;
67
+ } catch ( error ) {
68
+ // Handle errors gracefully
69
+ const errorMessage : MyMessage = {
70
+ id : generateId ( ) ,
71
+ role : "assistant" ,
72
+ text : `Sorry, I encountered an error: ${ error instanceof Error ? error . message : 'Unknown error' } . This is expected in mock mode for testing error handling.` ,
73
+ timestamp : Date . now ( ) ,
74
+ } ;
75
+
76
+ setMyMessages ( prev => [ ...prev , errorMessage ] ) ;
77
+ } finally {
78
+ setIsRunning ( false ) ;
79
+ }
80
+ } ;
81
+
82
+ // Add onEdit functionality
83
+ const onEdit = async ( message : AppendMessage ) => {
84
+ // Find the index where to insert the edited message
85
+ const index = myMessages . findIndex ( ( m ) => m . id === message . parentId ) + 1 ;
86
+
87
+ // Keep messages up to the parent
88
+ const newMessages = [ ...myMessages . slice ( 0 , index ) ] ;
89
+
90
+ // Add the edited message in your custom format
91
+ const editedMessage : MyMessage = {
92
+ id : generateId ( ) , // Always generate new ID for edited messages
93
+ role : "user" ,
94
+ text : typeof message . content === 'string' ? message . content : JSON . stringify ( message . content ) ,
95
+ timestamp : Date . now ( ) ,
96
+ } ;
97
+ newMessages . push ( editedMessage ) ;
98
+
99
+ setMyMessages ( newMessages ) ;
100
+ setIsRunning ( true ) ;
101
+
102
+ try {
103
+ // Generate new response
104
+ const response = await callYourAPI ( message ) ;
105
+
106
+ const assistantMessage : MyMessage = {
107
+ id : generateId ( ) ,
39
108
role : "assistant" ,
40
- content : response . content ,
109
+ text : response . content ,
110
+ timestamp : Date . now ( ) ,
41
111
} ;
42
112
43
- setMessages ( prev => [ ...prev , assistantMessage ] ) ;
113
+ newMessages . push ( assistantMessage ) ;
114
+ setMyMessages ( newMessages ) ;
44
115
} catch ( error ) {
45
116
// Handle errors gracefully
46
- const errorMessage : ThreadMessageLike = {
117
+ const errorMessage : MyMessage = {
118
+ id : generateId ( ) ,
47
119
role : "assistant" ,
48
- content : `Sorry, I encountered an error: ${ error instanceof Error ? error . message : 'Unknown error' } . This is expected in mock mode for testing error handling.` ,
120
+ text : `Sorry, I encountered an error: ${ error instanceof Error ? error . message : 'Unknown error' } ` ,
121
+ timestamp : Date . now ( ) ,
49
122
} ;
50
123
51
- setMessages ( prev => [ ...prev , errorMessage ] ) ;
124
+ newMessages . push ( errorMessage ) ;
125
+ setMyMessages ( newMessages ) ;
52
126
} finally {
53
127
setIsRunning ( false ) ;
54
128
}
55
129
} ;
56
130
57
- const runtime = useExternalStoreRuntime < ThreadMessageLike > ( {
58
- messages,
59
- setMessages ,
131
+ const runtime = useExternalStoreRuntime ( {
132
+ messages : myMessages , // Your custom message array
133
+ convertMessage , // Conversion function
60
134
isRunning,
61
135
onNew,
62
- convertMessage : ( message ) => message ,
136
+ onEdit , // Enable message editing
63
137
} ) ;
64
138
65
139
return (
66
140
< AssistantRuntimeProvider runtime = { runtime } >
67
141
{ children }
68
142
</ AssistantRuntimeProvider >
69
143
) ;
70
- }
144
+ }
0 commit comments