1
+ import { substituteLastUserMessage } from "./mcp" ;
2
+ import { ChatMessage , MessagePart , SlashCommand , UserChatMessage } from "../../index.js" ;
3
+
4
+ /**
5
+ * Test substitution of the prompt content into the history.
6
+ * actual content collected from debugging actual chats.
7
+ */
8
+ describe ( "substituteLastUserMessage" , ( ) => {
9
+ const systemMessage : ChatMessage = {
10
+ role : "system" ,
11
+ content : "Your are..."
12
+ } ;
13
+
14
+ const assistantEmptyMessage : ChatMessage = {
15
+ role : "assistant" ,
16
+ content : ""
17
+ } ;
18
+
19
+ const mcpMessage : ChatMessage = {
20
+ role : "user" ,
21
+ content : [ { type : "text" , text : "provide answer" } ]
22
+ } ;
23
+ const mcpHeadMessage : ChatMessage = {
24
+ role : "user" ,
25
+ content : [ { type : "text" , text : "this is important task" } ]
26
+ } ;
27
+ const mcpAssistantMessage : ChatMessage = {
28
+ role : "assistant" ,
29
+ content : [ { type : "text" , text : "I'm assistant" } ]
30
+ } ;
31
+
32
+ it ( "should handle only /echo on first question" , ( ) => {
33
+ // Input: `/echo `
34
+ const history : ChatMessage [ ] = [
35
+ systemMessage ,
36
+ {
37
+ role : "user" ,
38
+ content : [ { type : "text" , text : "/echo " } ]
39
+ } ,
40
+ assistantEmptyMessage
41
+ ] ;
42
+
43
+ const expected : ChatMessage [ ] = [
44
+ systemMessage ,
45
+ {
46
+ role : "user" ,
47
+ content : [ { type : "text" , text : "provide answer" } , { type : "text" , text : "" } ]
48
+ } ,
49
+ assistantEmptyMessage
50
+ ] ;
51
+
52
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
53
+ expect ( result ) . toEqual ( expected ) ;
54
+ } ) ;
55
+
56
+ it ( "should handle /echo with text on first question" , ( ) => {
57
+ // Input: `/echo hello`
58
+ const history : ChatMessage [ ] = [
59
+ systemMessage ,
60
+ {
61
+ role : "user" ,
62
+ content : [ { type : "text" , text : "/echo hello" } ]
63
+ } ,
64
+ assistantEmptyMessage
65
+ ] ;
66
+
67
+ const expected : ChatMessage [ ] = [
68
+ systemMessage ,
69
+ {
70
+ role : "user" ,
71
+ content : [ { type : "text" , text : "provide answer" } , { type : "text" , text : "hello" } ]
72
+ } ,
73
+ assistantEmptyMessage
74
+ ] ;
75
+
76
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
77
+ expect ( result ) . toEqual ( expected ) ;
78
+ } ) ;
79
+
80
+ it ( "should handle /echo with text and 1 context on first question" , ( ) => {
81
+ // Input: `/echo explain text.ts code`
82
+ const history : ChatMessage [ ] = [
83
+ systemMessage ,
84
+ {
85
+ role : "user" ,
86
+ content : [
87
+ { type : "text" , text : "text.ts code block" } ,
88
+ { type : "text" , text : "/echo explain text.ts code" }
89
+ ]
90
+ } ,
91
+ assistantEmptyMessage
92
+ ] ;
93
+
94
+ const expected : ChatMessage [ ] = [
95
+ systemMessage ,
96
+ {
97
+ role : "user" ,
98
+ content : [
99
+ { type : "text" , text : "text.ts code block" } ,
100
+ { type : "text" , text : "provide answer" } ,
101
+ { type : "text" , text : "explain text.ts code" }
102
+ ]
103
+ } ,
104
+ assistantEmptyMessage
105
+ ] ;
106
+
107
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
108
+ expect ( result ) . toEqual ( expected ) ;
109
+ } ) ;
110
+
111
+ it ( "should handle /echo with text and 2 contexts on first question" , ( ) => {
112
+ // Input: `/echo explain test.ts and test.py`
113
+ const history : ChatMessage [ ] = [
114
+ systemMessage ,
115
+ {
116
+ role : "user" ,
117
+ content : [
118
+ { type : "text" , text : "text.ts code block" } ,
119
+ { type : "text" , text : "text.py code block" } ,
120
+ { type : "text" , text : "/echo explain test.ts and test.py " }
121
+ ]
122
+ } ,
123
+ assistantEmptyMessage
124
+ ] ;
125
+
126
+ const expected : ChatMessage [ ] = [
127
+ systemMessage ,
128
+ {
129
+ role : "user" ,
130
+ content : [
131
+ { type : "text" , text : "text.ts code block" } ,
132
+ { type : "text" , text : "text.py code block" } ,
133
+ { type : "text" , text : "provide answer" } ,
134
+ { type : "text" , text : "explain test.ts and test.py " }
135
+ ]
136
+ } ,
137
+ assistantEmptyMessage
138
+ ] ;
139
+
140
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
141
+ expect ( result ) . toEqual ( expected ) ;
142
+ } ) ;
143
+
144
+ it ( "should handle /echo with text and image on first question" , ( ) => {
145
+ // Input: `/echo explain`
146
+ const history : ChatMessage [ ] = [
147
+ systemMessage ,
148
+ {
149
+ role : "user" ,
150
+ content : [
151
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
152
+ { type : "text" , text : "/echo explain" }
153
+ ]
154
+ } ,
155
+ assistantEmptyMessage
156
+ ] ;
157
+
158
+ const expected : ChatMessage [ ] = [
159
+ systemMessage ,
160
+ {
161
+ role : "user" ,
162
+ content : [
163
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
164
+ { type : "text" , text : "provide answer" } ,
165
+ { type : "text" , text : "explain" }
166
+ ]
167
+ } ,
168
+ assistantEmptyMessage
169
+ ] ;
170
+
171
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
172
+ expect ( result ) . toEqual ( expected ) ;
173
+ } ) ;
174
+
175
+ it ( "should handle /echo with text, image, and context on first question" , ( ) => {
176
+ // Input: `/echo explain test.ts`
177
+ const history : ChatMessage [ ] = [
178
+ systemMessage ,
179
+ {
180
+ role : "user" ,
181
+ content : [
182
+ { type : "text" , text : "text.ts code block" } ,
183
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
184
+ { type : "text" , text : "/echo explain test.ts" }
185
+ ]
186
+ } ,
187
+ assistantEmptyMessage
188
+ ] ;
189
+
190
+ const expected : ChatMessage [ ] = [
191
+ systemMessage ,
192
+ {
193
+ role : "user" ,
194
+ content : [
195
+ { type : "text" , text : "text.ts code block" } ,
196
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
197
+ { type : "text" , text : "provide answer" } ,
198
+ { type : "text" , text : "explain test.ts" }
199
+ ]
200
+ } ,
201
+ assistantEmptyMessage
202
+ ] ;
203
+
204
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
205
+ expect ( result ) . toEqual ( expected ) ;
206
+ } ) ;
207
+
208
+ it ( "should handle only /echo on second question" , ( ) => {
209
+ // Input: `/echo `
210
+ const history : ChatMessage [ ] = [
211
+ systemMessage ,
212
+ { role : "user" , content : "first history" } ,
213
+ { role : "assistant" , content : "answer" } ,
214
+ {
215
+ role : "user" ,
216
+ content : [ { type : "text" , text : "/echo " } ]
217
+ } ,
218
+ assistantEmptyMessage
219
+ ] ;
220
+
221
+ const expected : ChatMessage [ ] = [
222
+ systemMessage ,
223
+ { role : "user" , content : "first history" } ,
224
+ { role : "assistant" , content : "answer" } ,
225
+ {
226
+ role : "user" ,
227
+ content : [ { type : "text" , text : "provide answer" } , { type : "text" , text : "" } ]
228
+ } ,
229
+ assistantEmptyMessage
230
+ ] ;
231
+
232
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
233
+ expect ( result ) . toEqual ( expected ) ;
234
+ } ) ;
235
+
236
+ it ( "should handle /echo with text and resource on second question" , ( ) => {
237
+ // Same as first question but with more history at the start
238
+ const history : ChatMessage [ ] = [
239
+ systemMessage ,
240
+ { role : "user" , content : "previous question" } ,
241
+ { role : "assistant" , content : "previous answer" } ,
242
+ {
243
+ role : "user" ,
244
+ content : [
245
+ { type : "text" , text : "text.ts code block" } ,
246
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
247
+ { type : "text" , text : "/echo explain test.ts" }
248
+ ]
249
+ } ,
250
+ assistantEmptyMessage
251
+ ] ;
252
+
253
+ const expected : ChatMessage [ ] = [
254
+ systemMessage ,
255
+ { role : "user" , content : "previous question" } ,
256
+ { role : "assistant" , content : "previous answer" } ,
257
+ {
258
+ role : "user" ,
259
+ content : [
260
+ { type : "text" , text : "text.ts code block" } ,
261
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
262
+ { type : "text" , text : "provide answer" } ,
263
+ { type : "text" , text : "explain test.ts" }
264
+ ]
265
+ } ,
266
+ assistantEmptyMessage
267
+ ] ;
268
+
269
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpMessage ] ) ;
270
+ expect ( result ) . toEqual ( expected ) ;
271
+ } ) ;
272
+
273
+ it ( "should handle /echo with text and resource with multisection prompt" , ( ) => {
274
+ // Same as first question but with more history at the start
275
+ const history : ChatMessage [ ] = [
276
+ systemMessage ,
277
+ { role : "user" , content : "previous question" } ,
278
+ { role : "assistant" , content : "previous answer" } ,
279
+ {
280
+ role : "user" ,
281
+ content : [
282
+ { type : "text" , text : "text.ts code block" } ,
283
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
284
+ { type : "text" , text : "/echo explain test.ts" }
285
+ ]
286
+ } ,
287
+ assistantEmptyMessage
288
+ ] ;
289
+
290
+ const expected : ChatMessage [ ] = [
291
+ systemMessage ,
292
+ { role : "user" , content : "previous question" } ,
293
+ { role : "assistant" , content : "previous answer" } ,
294
+ mcpHeadMessage ,
295
+ mcpAssistantMessage ,
296
+ {
297
+ role : "user" ,
298
+ content : [
299
+ { type : "text" , text : "text.ts code block" } ,
300
+ { type : "imageUrl" , imageUrl :{ url : "data:..." } } ,
301
+ { type : "text" , text : "provide answer" } ,
302
+ { type : "text" , text : "explain test.ts" }
303
+ ]
304
+ } ,
305
+ assistantEmptyMessage
306
+ ] ;
307
+
308
+ const result = substituteLastUserMessage ( history , "/echo " , [ mcpHeadMessage , mcpAssistantMessage , mcpMessage ] ) ;
309
+ expect ( result ) . toEqual ( expected ) ;
310
+ } ) ;
311
+ } ) ;
0 commit comments