@eeacms/volto-eea-chatbot 2.0.1 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/.eslintrc.js +6 -6
  2. package/CHANGELOG.md +2 -0
  3. package/jest-addon.config.js +1 -0
  4. package/package.json +1 -1
  5. package/src/ChatBlock/ChatBlockEdit.jsx +2 -1
  6. package/src/ChatBlock/chat/AIMessage.tsx +20 -16
  7. package/src/ChatBlock/chat/ChatMessage.tsx +1 -1
  8. package/src/ChatBlock/chat/ChatWindow.tsx +10 -11
  9. package/src/ChatBlock/chat/UserMessage.tsx +4 -4
  10. package/src/ChatBlock/components/AutoResizeTextarea.jsx +1 -1
  11. package/src/ChatBlock/components/ChatMessageFeedback.jsx +2 -2
  12. package/src/ChatBlock/components/EmptyState.jsx +1 -1
  13. package/src/ChatBlock/components/FeedbackModal.jsx +1 -1
  14. package/src/ChatBlock/components/HalloumiFeedback.jsx +2 -2
  15. package/src/ChatBlock/components/Source.jsx +2 -2
  16. package/src/ChatBlock/components/UserActionsToolbar.jsx +3 -3
  17. package/src/ChatBlock/components/WebResultIcon.tsx +2 -2
  18. package/src/ChatBlock/components/markdown/ClaimModal.jsx +3 -3
  19. package/src/ChatBlock/components/markdown/ClaimSegments.jsx +4 -4
  20. package/src/ChatBlock/components/markdown/{index.js → index.jsx} +1 -1
  21. package/src/ChatBlock/hooks/useChatController.ts +7 -4
  22. package/src/ChatBlock/hooks/useChatStreaming.ts +4 -4
  23. package/src/ChatBlock/hooks/useToolDisplayTiming.ts +1 -1
  24. package/src/ChatBlock/packets/MultiToolRenderer.tsx +11 -12
  25. package/src/ChatBlock/packets/RendererComponent.tsx +6 -3
  26. package/src/ChatBlock/packets/renderers/CustomToolRenderer.tsx +3 -3
  27. package/src/ChatBlock/packets/renderers/FetchToolRenderer.tsx +3 -3
  28. package/src/ChatBlock/packets/renderers/ImageToolRenderer.tsx +3 -3
  29. package/src/ChatBlock/packets/renderers/MessageTextRenderer.tsx +8 -8
  30. package/src/ChatBlock/packets/renderers/ReasoningRenderer.tsx +5 -5
  31. package/src/ChatBlock/packets/renderers/SearchToolRenderer.tsx +10 -10
  32. package/src/ChatBlock/services/messageProcessor.ts +6 -3
  33. package/src/ChatBlock/services/packetUtils.ts +2 -2
  34. package/src/ChatBlock/services/streamingService.ts +8 -2
  35. package/src/ChatBlock/utils/citations.ts +1 -1
  36. package/src/halloumi/filtering.test.js +199 -1
  37. package/src/ChatBlock/tests/AIMessage.test.jsx +0 -95
  38. package/src/ChatBlock/tests/AutoResizeTextarea.test.jsx +0 -49
  39. package/src/ChatBlock/tests/BlinkingDot.test.jsx +0 -71
  40. package/src/ChatBlock/tests/ChatMessage.test.jsx +0 -75
  41. package/src/ChatBlock/tests/ChatMessageFeedback.test.jsx +0 -73
  42. package/src/ChatBlock/tests/Citation.test.jsx +0 -107
  43. package/src/ChatBlock/tests/ClaimModal.test.jsx +0 -136
  44. package/src/ChatBlock/tests/ClaimSegments.test.jsx +0 -206
  45. package/src/ChatBlock/tests/CustomToolRenderer.test.jsx +0 -241
  46. package/src/ChatBlock/tests/EmptyState.test.jsx +0 -137
  47. package/src/ChatBlock/tests/FeedbackModal.test.jsx +0 -138
  48. package/src/ChatBlock/tests/FetchToolRenderer.test.jsx +0 -161
  49. package/src/ChatBlock/tests/HalloumiFeedback.test.jsx +0 -94
  50. package/src/ChatBlock/tests/ImageToolRenderer.test.jsx +0 -178
  51. package/src/ChatBlock/tests/MessageTextRenderer.test.jsx +0 -227
  52. package/src/ChatBlock/tests/MultiToolRenderer.test.jsx +0 -134
  53. package/src/ChatBlock/tests/QualityCheckToggle.test.jsx +0 -105
  54. package/src/ChatBlock/tests/ReasoningRenderer.test.jsx +0 -163
  55. package/src/ChatBlock/tests/RelatedQuestions.test.jsx +0 -215
  56. package/src/ChatBlock/tests/RenderClaimView.test.jsx +0 -191
  57. package/src/ChatBlock/tests/RendererComponent.test.jsx +0 -139
  58. package/src/ChatBlock/tests/SearchToolRenderer.test.jsx +0 -295
  59. package/src/ChatBlock/tests/Source.test.jsx +0 -79
  60. package/src/ChatBlock/tests/SourceChip.test.jsx +0 -108
  61. package/src/ChatBlock/tests/Spinner.test.jsx +0 -18
  62. package/src/ChatBlock/tests/UserActionsToolbar.test.jsx +0 -135
  63. package/src/ChatBlock/tests/UserMessage.test.jsx +0 -83
  64. package/src/ChatBlock/tests/WebResultIcon.test.jsx +0 -61
  65. package/src/ChatBlock/tests/citations.test.js +0 -114
  66. package/src/ChatBlock/tests/index.test.js +0 -51
  67. package/src/ChatBlock/tests/messageProcessor.test.jsx +0 -438
  68. package/src/ChatBlock/tests/packetUtils.test.js +0 -158
  69. package/src/ChatBlock/tests/schema.test.js +0 -166
  70. package/src/ChatBlock/tests/streamingService.test.js +0 -467
  71. package/src/ChatBlock/tests/useChatController.test.jsx +0 -268
  72. package/src/ChatBlock/tests/useChatStreaming.test.jsx +0 -163
  73. package/src/ChatBlock/tests/useDeepCompareMemoize.test.js +0 -107
  74. package/src/ChatBlock/tests/useMarked.test.jsx +0 -107
  75. package/src/ChatBlock/tests/useQualityMarkers.test.jsx +0 -150
  76. package/src/ChatBlock/tests/useScrollonStream.test.jsx +0 -121
  77. package/src/ChatBlock/tests/useToolDisplayTiming.test.jsx +0 -151
  78. package/src/ChatBlock/tests/utils.test.jsx +0 -241
  79. package/src/ChatBlock/tests/withOnyxData.test.jsx +0 -81
  80. /package/src/ChatBlock/{schema.js → schema.jsx} +0 -0
@@ -1,438 +0,0 @@
1
- import { MessageProcessor } from '../services/messageProcessor';
2
- import { PacketType } from '../types/streamingModels';
3
-
4
- describe('MessageProcessor', () => {
5
- let processor;
6
-
7
- beforeEach(() => {
8
- processor = new MessageProcessor(1, null);
9
- });
10
-
11
- it('should initialize with empty state', () => {
12
- const result = processor.getMessage();
13
- expect(result.groupedPackets).toEqual([]);
14
- expect(result.toolPackets).toEqual([]);
15
- expect(result.displayPackets).toEqual([]);
16
- expect(result.citations || {}).toEqual({});
17
- expect(result.documents).toEqual(null);
18
- expect(result.isComplete).toBe(false);
19
- });
20
-
21
- it('should process text message packets', () => {
22
- const packets = [
23
- {
24
- ind: 0,
25
- obj: {
26
- type: PacketType.MESSAGE_START,
27
- id: 'msg1',
28
- content: 'Hello world',
29
- final_documents: null,
30
- },
31
- },
32
- ];
33
-
34
- processor.addPackets(packets);
35
- const result = processor.getMessage();
36
- expect(result.groupedPackets).toHaveLength(1);
37
- expect(result.displayPackets).toContain(0);
38
- expect(result.groupedPackets[0].packets[0].obj.content).toBe('Hello world');
39
- });
40
-
41
- it('should process search tool packets', () => {
42
- const packets = [
43
- {
44
- ind: 0,
45
- obj: {
46
- type: PacketType.SEARCH_TOOL_START,
47
- search_query: 'test query',
48
- },
49
- },
50
- ];
51
-
52
- processor.addPackets(packets);
53
- const result = processor.getMessage();
54
- expect(result.groupedPackets).toHaveLength(1);
55
- expect(result.toolPackets).toContain(0);
56
- });
57
-
58
- it('should process citation packets', () => {
59
- const packets = [
60
- {
61
- ind: 0,
62
- obj: {
63
- type: PacketType.CITATION_DELTA,
64
- citations: [{ citation_num: 1, document_id: 'doc123' }],
65
- },
66
- },
67
- ];
68
-
69
- processor.addPackets(packets);
70
- const result = processor.getMessage();
71
- expect(result.citations).toEqual({ 1: 'doc123' });
72
- });
73
-
74
- it('should process document packets', () => {
75
- const packets = [
76
- {
77
- ind: 0,
78
- obj: {
79
- type: PacketType.SEARCH_TOOL_DELTA,
80
- documents: [
81
- {
82
- document_id: 'doc123',
83
- semantic_identifier: 'Test Document',
84
- link: 'https://example.com',
85
- },
86
- ],
87
- },
88
- },
89
- ];
90
-
91
- processor.addPackets(packets);
92
- const result = processor.getMessage();
93
- expect(result.documents).toHaveLength(1);
94
- expect(result.documents[0].document_id).toBe('doc123');
95
- });
96
-
97
- it('should process error packets', () => {
98
- const packets = [
99
- {
100
- ind: 0,
101
- obj: {
102
- type: PacketType.ERROR,
103
- error: 'Something went wrong',
104
- },
105
- },
106
- ];
107
-
108
- processor.addPackets(packets);
109
- const result = processor.getMessage();
110
- expect(result.error).toBe('Something went wrong');
111
- });
112
-
113
- it('should mark as complete when stop packet received', () => {
114
- const packets = [
115
- {
116
- ind: 0,
117
- obj: {
118
- type: PacketType.MESSAGE_DELTA,
119
- content: 'Hello',
120
- },
121
- },
122
- {
123
- ind: 1,
124
- obj: {
125
- type: PacketType.STOP,
126
- },
127
- },
128
- ];
129
-
130
- processor.addPackets(packets);
131
- const result = processor.getMessage();
132
- expect(result.isComplete).toBe(true);
133
- });
134
-
135
- it('should reset processor state', () => {
136
- const packets = [
137
- {
138
- ind: 0,
139
- obj: {
140
- type: PacketType.MESSAGE_DELTA,
141
- content: 'Hello',
142
- },
143
- },
144
- ];
145
-
146
- processor.addPackets(packets);
147
- processor.reset();
148
-
149
- const result = processor.getMessage();
150
- expect(result.groupedPackets).toEqual([]);
151
- expect(result.documents).toEqual(null);
152
- expect(result.citations || {}).toEqual({});
153
- });
154
-
155
- it('should process MESSAGE_END_ID_INFO packets and expose messageIds', () => {
156
- processor.addPackets([
157
- {
158
- ind: -1,
159
- obj: {
160
- type: PacketType.MESSAGE_END_ID_INFO,
161
- user_message_id: 42,
162
- reserved_assistant_message_id: 43,
163
- },
164
- },
165
- ]);
166
-
167
- expect(processor.messageIds).toEqual({
168
- userMessageId: 42,
169
- assistantMessageId: 43,
170
- });
171
- });
172
-
173
- it('should set isFinalMessageComing on MESSAGE_START', () => {
174
- expect(processor.isFinalMessageComing).toBe(false);
175
-
176
- processor.addPackets([
177
- {
178
- ind: 0,
179
- obj: {
180
- type: PacketType.MESSAGE_START,
181
- id: 'msg1',
182
- content: 'Hi',
183
- final_documents: null,
184
- },
185
- },
186
- ]);
187
-
188
- expect(processor.isFinalMessageComing).toBe(true);
189
- });
190
-
191
- it('should set isFinalMessageComing on IMAGE_GENERATION_TOOL_START', () => {
192
- processor.addPackets([
193
- {
194
- ind: 0,
195
- obj: { type: PacketType.IMAGE_GENERATION_TOOL_START },
196
- },
197
- ]);
198
-
199
- expect(processor.isFinalMessageComing).toBe(true);
200
- });
201
-
202
- it('should handle SECTION_END with synthetic packet mapping', () => {
203
- // First start an index, then send SECTION_END
204
- processor.addPackets([
205
- {
206
- ind: 5,
207
- obj: {
208
- type: PacketType.SEARCH_TOOL_START,
209
- },
210
- },
211
- ]);
212
-
213
- // SECTION_END should get remapped to ind=5
214
- processor.addPackets([
215
- {
216
- ind: -1,
217
- obj: { type: PacketType.SECTION_END },
218
- },
219
- ]);
220
-
221
- const result = processor.getMessage();
222
- // The SECTION_END should be stored with ind=5
223
- const sectionEndPackets = result.packets.filter(
224
- (p) => p.obj.type === PacketType.SECTION_END,
225
- );
226
- expect(sectionEndPackets).toHaveLength(1);
227
- expect(sectionEndPackets[0].ind).toBe(5);
228
- });
229
-
230
- it('should skip SECTION_END when no indices started', () => {
231
- processor.addPackets([
232
- {
233
- ind: -1,
234
- obj: { type: PacketType.SECTION_END },
235
- },
236
- ]);
237
-
238
- const result = processor.getMessage();
239
- expect(result.packets).toHaveLength(0);
240
- });
241
-
242
- it('should extract tool call from search tool packets on complete', () => {
243
- processor.addPackets([
244
- {
245
- ind: 0,
246
- obj: { type: PacketType.SEARCH_TOOL_START },
247
- },
248
- {
249
- ind: 0,
250
- obj: {
251
- type: PacketType.SEARCH_TOOL_DELTA,
252
- documents: [
253
- {
254
- document_id: 'doc1',
255
- semantic_identifier: 'Doc 1',
256
- link: 'http://example.com',
257
- blurb: 'some content',
258
- },
259
- ],
260
- },
261
- },
262
- {
263
- ind: -1,
264
- obj: { type: PacketType.SECTION_END },
265
- },
266
- {
267
- ind: 1,
268
- obj: {
269
- type: PacketType.MESSAGE_START,
270
- id: 'msg1',
271
- content: 'Answer',
272
- final_documents: null,
273
- },
274
- },
275
- { ind: 2, obj: { type: PacketType.STOP } },
276
- ]);
277
-
278
- const result = processor.getMessage();
279
- expect(result.isComplete).toBe(true);
280
- expect(result.toolCall).not.toBeNull();
281
- expect(result.toolCall.tool_name).toBe('run_search');
282
- expect(result.toolCall.tool_result).toHaveLength(1);
283
- expect(result.toolCall.tool_result[0].document_id).toBe('doc1');
284
- });
285
-
286
- it('should return null toolCall when no search tool packets', () => {
287
- processor.addPackets([
288
- {
289
- ind: 0,
290
- obj: { type: PacketType.MESSAGE_DELTA, content: 'Hello' },
291
- },
292
- { ind: 1, obj: { type: PacketType.STOP } },
293
- ]);
294
-
295
- const result = processor.getMessage();
296
- expect(result.isComplete).toBe(true);
297
- expect(result.toolCall).toBeNull();
298
- });
299
-
300
- it('should deduplicate documents by document_id', () => {
301
- const doc = {
302
- document_id: 'dup1',
303
- semantic_identifier: 'Doc',
304
- link: 'http://example.com',
305
- };
306
-
307
- processor.addPackets([
308
- { ind: 0, obj: { type: PacketType.SEARCH_TOOL_DELTA, documents: [doc] } },
309
- { ind: 0, obj: { type: PacketType.SEARCH_TOOL_DELTA, documents: [doc] } },
310
- ]);
311
-
312
- const result = processor.getMessage();
313
- expect(result.documents).toHaveLength(1);
314
- });
315
-
316
- it('should deduplicate citations by citation_num', () => {
317
- processor.addPackets([
318
- {
319
- ind: 0,
320
- obj: {
321
- type: PacketType.CITATION_DELTA,
322
- citations: [{ citation_num: 1, document_id: 'doc1' }],
323
- },
324
- },
325
- {
326
- ind: 0,
327
- obj: {
328
- type: PacketType.CITATION_DELTA,
329
- citations: [{ citation_num: 1, document_id: 'doc2' }],
330
- },
331
- },
332
- ]);
333
-
334
- const result = processor.getMessage();
335
- // First citation wins
336
- expect(result.citations).toEqual({ 1: 'doc1' });
337
- });
338
-
339
- it('should accumulate text from MESSAGE_START and MESSAGE_DELTA', () => {
340
- processor.addPackets([
341
- {
342
- ind: 0,
343
- obj: {
344
- type: PacketType.MESSAGE_START,
345
- id: 'msg1',
346
- content: 'Hello ',
347
- final_documents: null,
348
- },
349
- },
350
- {
351
- ind: 0,
352
- obj: { type: PacketType.MESSAGE_DELTA, content: 'world' },
353
- },
354
- ]);
355
-
356
- const result = processor.getMessage();
357
- expect(result.message).toBe('Hello world');
358
- });
359
-
360
- it('should process documents from FETCH_TOOL_START', () => {
361
- processor.addPackets([
362
- {
363
- ind: 0,
364
- obj: {
365
- type: PacketType.FETCH_TOOL_START,
366
- documents: [
367
- {
368
- document_id: 'fetch1',
369
- semantic_identifier: 'Fetched',
370
- link: 'http://fetch.com',
371
- },
372
- ],
373
- queries: null,
374
- },
375
- },
376
- ]);
377
-
378
- const result = processor.getMessage();
379
- expect(result.documents).toHaveLength(1);
380
- expect(result.documents[0].document_id).toBe('fetch1');
381
- });
382
-
383
- it('should process documents from MESSAGE_START final_documents', () => {
384
- processor.addPackets([
385
- {
386
- ind: 0,
387
- obj: {
388
- type: PacketType.MESSAGE_START,
389
- id: 'msg1',
390
- content: 'Hello',
391
- final_documents: [
392
- {
393
- document_id: 'fd1',
394
- semantic_identifier: 'Final Doc',
395
- link: 'http://final.com',
396
- },
397
- ],
398
- },
399
- },
400
- ]);
401
-
402
- const result = processor.getMessage();
403
- expect(result.documents).toHaveLength(1);
404
- expect(result.documents[0].document_id).toBe('fd1');
405
- });
406
-
407
- it('should mark complete on ERROR packet', () => {
408
- processor.addPackets([
409
- {
410
- ind: 0,
411
- obj: { type: PacketType.ERROR, error: 'fail' },
412
- },
413
- ]);
414
-
415
- expect(processor.isComplete).toBe(true);
416
- });
417
-
418
- it('should return null toolCall when search has no documents', () => {
419
- processor.addPackets([
420
- { ind: 0, obj: { type: PacketType.SEARCH_TOOL_START } },
421
- {
422
- ind: 0,
423
- obj: { type: PacketType.SEARCH_TOOL_DELTA, documents: [] },
424
- },
425
- { ind: 1, obj: { type: PacketType.STOP } },
426
- ]);
427
-
428
- const result = processor.getMessage();
429
- expect(result.toolCall).toBeNull();
430
- });
431
-
432
- it('should set nodeId and parentNodeId from constructor', () => {
433
- const p = new MessageProcessor(10, 5);
434
- const msg = p.getMessage();
435
- expect(msg.nodeId).toBe(10);
436
- expect(msg.parentNodeId).toBe(5);
437
- });
438
- });
@@ -1,158 +0,0 @@
1
- import {
2
- getSynteticPacket,
3
- isToolPacket,
4
- isDisplayPacket,
5
- isFinalAnswerComplete,
6
- } from '../services/packetUtils';
7
- import { PacketType } from '../types/streamingModels';
8
-
9
- describe('packetUtils', () => {
10
- describe('getSynteticPacket', () => {
11
- it('creates a synthetic packet with given index and type', () => {
12
- const packet = getSynteticPacket(1, PacketType.MESSAGE_START);
13
- expect(packet).toEqual({
14
- ind: 1,
15
- obj: { type: PacketType.MESSAGE_START },
16
- });
17
- });
18
-
19
- it('creates packets with different types', () => {
20
- const searchPacket = getSynteticPacket(2, PacketType.SEARCH_TOOL_START);
21
- expect(searchPacket.ind).toBe(2);
22
- expect(searchPacket.obj.type).toBe(PacketType.SEARCH_TOOL_START);
23
- });
24
- });
25
-
26
- describe('isToolPacket', () => {
27
- it('returns true for SEARCH_TOOL_START packets', () => {
28
- const packet = { ind: 1, obj: { type: PacketType.SEARCH_TOOL_START } };
29
- expect(isToolPacket(packet)).toBe(true);
30
- });
31
-
32
- it('returns true for SEARCH_TOOL_DELTA packets', () => {
33
- const packet = { ind: 1, obj: { type: PacketType.SEARCH_TOOL_DELTA } };
34
- expect(isToolPacket(packet)).toBe(true);
35
- });
36
-
37
- it('returns true for CUSTOM_TOOL_START packets', () => {
38
- const packet = { ind: 1, obj: { type: PacketType.CUSTOM_TOOL_START } };
39
- expect(isToolPacket(packet)).toBe(true);
40
- });
41
-
42
- it('returns true for CUSTOM_TOOL_DELTA packets', () => {
43
- const packet = { ind: 1, obj: { type: PacketType.CUSTOM_TOOL_DELTA } };
44
- expect(isToolPacket(packet)).toBe(true);
45
- });
46
-
47
- it('returns true for REASONING_START packets', () => {
48
- const packet = { ind: 1, obj: { type: PacketType.REASONING_START } };
49
- expect(isToolPacket(packet)).toBe(true);
50
- });
51
-
52
- it('returns true for REASONING_DELTA packets', () => {
53
- const packet = { ind: 1, obj: { type: PacketType.REASONING_DELTA } };
54
- expect(isToolPacket(packet)).toBe(true);
55
- });
56
-
57
- it('returns true for FETCH_TOOL_START packets', () => {
58
- const packet = { ind: 1, obj: { type: PacketType.FETCH_TOOL_START } };
59
- expect(isToolPacket(packet)).toBe(true);
60
- });
61
-
62
- it('returns false for MESSAGE_START packets', () => {
63
- const packet = { ind: 1, obj: { type: PacketType.MESSAGE_START } };
64
- expect(isToolPacket(packet)).toBe(false);
65
- });
66
-
67
- it('returns false for MESSAGE_DELTA packets', () => {
68
- const packet = { ind: 1, obj: { type: PacketType.MESSAGE_DELTA } };
69
- expect(isToolPacket(packet)).toBe(false);
70
- });
71
-
72
- it('returns false for STOP packets', () => {
73
- const packet = { ind: 1, obj: { type: PacketType.STOP } };
74
- expect(isToolPacket(packet)).toBe(false);
75
- });
76
- });
77
-
78
- describe('isDisplayPacket', () => {
79
- it('returns true for MESSAGE_START packets', () => {
80
- const packet = { ind: 1, obj: { type: PacketType.MESSAGE_START } };
81
- expect(isDisplayPacket(packet)).toBe(true);
82
- });
83
-
84
- it('returns true for IMAGE_GENERATION_TOOL_START packets', () => {
85
- const packet = {
86
- ind: 1,
87
- obj: { type: PacketType.IMAGE_GENERATION_TOOL_START },
88
- };
89
- expect(isDisplayPacket(packet)).toBe(true);
90
- });
91
-
92
- it('returns false for SEARCH_TOOL_START packets', () => {
93
- const packet = { ind: 1, obj: { type: PacketType.SEARCH_TOOL_START } };
94
- expect(isDisplayPacket(packet)).toBe(false);
95
- });
96
-
97
- it('returns false for MESSAGE_DELTA packets', () => {
98
- const packet = { ind: 1, obj: { type: PacketType.MESSAGE_DELTA } };
99
- expect(isDisplayPacket(packet)).toBe(false);
100
- });
101
- });
102
-
103
- describe('isFinalAnswerComplete', () => {
104
- it('returns false when no packets', () => {
105
- expect(isFinalAnswerComplete([])).toBe(false);
106
- });
107
-
108
- it('returns false when no MESSAGE_START packet', () => {
109
- const packets = [
110
- { ind: 1, obj: { type: PacketType.MESSAGE_DELTA, content: 'Hello' } },
111
- { ind: 1, obj: { type: PacketType.SECTION_END } },
112
- ];
113
- expect(isFinalAnswerComplete(packets)).toBe(false);
114
- });
115
-
116
- it('returns false when MESSAGE_START exists but no matching SECTION_END', () => {
117
- const packets = [
118
- {
119
- ind: 1,
120
- obj: { type: PacketType.MESSAGE_START, content: '', id: '1' },
121
- },
122
- { ind: 1, obj: { type: PacketType.MESSAGE_DELTA, content: 'Hello' } },
123
- ];
124
- expect(isFinalAnswerComplete(packets)).toBe(false);
125
- });
126
-
127
- it('returns true when MESSAGE_START and matching SECTION_END exist', () => {
128
- const packets = [
129
- {
130
- ind: 1,
131
- obj: { type: PacketType.MESSAGE_START, content: '', id: '1' },
132
- },
133
- { ind: 1, obj: { type: PacketType.MESSAGE_DELTA, content: 'Hello' } },
134
- { ind: 1, obj: { type: PacketType.SECTION_END } },
135
- ];
136
- expect(isFinalAnswerComplete(packets)).toBe(true);
137
- });
138
-
139
- it('returns true when IMAGE_GENERATION_TOOL_START and matching SECTION_END exist', () => {
140
- const packets = [
141
- { ind: 2, obj: { type: PacketType.IMAGE_GENERATION_TOOL_START } },
142
- { ind: 2, obj: { type: PacketType.SECTION_END } },
143
- ];
144
- expect(isFinalAnswerComplete(packets)).toBe(true);
145
- });
146
-
147
- it('returns false when SECTION_END has different index', () => {
148
- const packets = [
149
- {
150
- ind: 1,
151
- obj: { type: PacketType.MESSAGE_START, content: '', id: '1' },
152
- },
153
- { ind: 2, obj: { type: PacketType.SECTION_END } },
154
- ];
155
- expect(isFinalAnswerComplete(packets)).toBe(false);
156
- });
157
- });
158
- });