@eeacms/volto-eea-chatbot 2.0.0 → 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 (81) hide show
  1. package/.eslintrc.js +6 -6
  2. package/CHANGELOG.md +12 -1
  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/index.js +8 -0
  25. package/src/ChatBlock/packets/MultiToolRenderer.tsx +11 -12
  26. package/src/ChatBlock/packets/RendererComponent.tsx +6 -3
  27. package/src/ChatBlock/packets/renderers/CustomToolRenderer.tsx +3 -3
  28. package/src/ChatBlock/packets/renderers/FetchToolRenderer.tsx +3 -3
  29. package/src/ChatBlock/packets/renderers/ImageToolRenderer.tsx +3 -3
  30. package/src/ChatBlock/packets/renderers/MessageTextRenderer.tsx +8 -8
  31. package/src/ChatBlock/packets/renderers/ReasoningRenderer.tsx +5 -5
  32. package/src/ChatBlock/packets/renderers/SearchToolRenderer.tsx +10 -10
  33. package/src/ChatBlock/services/messageProcessor.ts +6 -3
  34. package/src/ChatBlock/services/packetUtils.ts +2 -2
  35. package/src/ChatBlock/services/streamingService.ts +8 -2
  36. package/src/ChatBlock/utils/citations.ts +1 -1
  37. package/src/halloumi/filtering.test.js +199 -1
  38. package/src/ChatBlock/tests/AIMessage.test.jsx +0 -95
  39. package/src/ChatBlock/tests/AutoResizeTextarea.test.jsx +0 -49
  40. package/src/ChatBlock/tests/BlinkingDot.test.jsx +0 -71
  41. package/src/ChatBlock/tests/ChatMessage.test.jsx +0 -75
  42. package/src/ChatBlock/tests/ChatMessageFeedback.test.jsx +0 -73
  43. package/src/ChatBlock/tests/Citation.test.jsx +0 -107
  44. package/src/ChatBlock/tests/ClaimModal.test.jsx +0 -136
  45. package/src/ChatBlock/tests/ClaimSegments.test.jsx +0 -206
  46. package/src/ChatBlock/tests/CustomToolRenderer.test.jsx +0 -241
  47. package/src/ChatBlock/tests/EmptyState.test.jsx +0 -137
  48. package/src/ChatBlock/tests/FeedbackModal.test.jsx +0 -138
  49. package/src/ChatBlock/tests/FetchToolRenderer.test.jsx +0 -161
  50. package/src/ChatBlock/tests/HalloumiFeedback.test.jsx +0 -94
  51. package/src/ChatBlock/tests/ImageToolRenderer.test.jsx +0 -178
  52. package/src/ChatBlock/tests/MessageTextRenderer.test.jsx +0 -227
  53. package/src/ChatBlock/tests/MultiToolRenderer.test.jsx +0 -134
  54. package/src/ChatBlock/tests/QualityCheckToggle.test.jsx +0 -105
  55. package/src/ChatBlock/tests/ReasoningRenderer.test.jsx +0 -163
  56. package/src/ChatBlock/tests/RelatedQuestions.test.jsx +0 -215
  57. package/src/ChatBlock/tests/RenderClaimView.test.jsx +0 -191
  58. package/src/ChatBlock/tests/RendererComponent.test.jsx +0 -139
  59. package/src/ChatBlock/tests/SearchToolRenderer.test.jsx +0 -295
  60. package/src/ChatBlock/tests/Source.test.jsx +0 -79
  61. package/src/ChatBlock/tests/SourceChip.test.jsx +0 -108
  62. package/src/ChatBlock/tests/Spinner.test.jsx +0 -18
  63. package/src/ChatBlock/tests/UserActionsToolbar.test.jsx +0 -135
  64. package/src/ChatBlock/tests/UserMessage.test.jsx +0 -83
  65. package/src/ChatBlock/tests/WebResultIcon.test.jsx +0 -61
  66. package/src/ChatBlock/tests/citations.test.js +0 -114
  67. package/src/ChatBlock/tests/index.test.js +0 -51
  68. package/src/ChatBlock/tests/messageProcessor.test.jsx +0 -438
  69. package/src/ChatBlock/tests/packetUtils.test.js +0 -158
  70. package/src/ChatBlock/tests/schema.test.js +0 -166
  71. package/src/ChatBlock/tests/streamingService.test.js +0 -467
  72. package/src/ChatBlock/tests/useChatController.test.jsx +0 -268
  73. package/src/ChatBlock/tests/useChatStreaming.test.jsx +0 -163
  74. package/src/ChatBlock/tests/useDeepCompareMemoize.test.js +0 -107
  75. package/src/ChatBlock/tests/useMarked.test.jsx +0 -107
  76. package/src/ChatBlock/tests/useQualityMarkers.test.jsx +0 -150
  77. package/src/ChatBlock/tests/useScrollonStream.test.jsx +0 -121
  78. package/src/ChatBlock/tests/useToolDisplayTiming.test.jsx +0 -151
  79. package/src/ChatBlock/tests/utils.test.jsx +0 -241
  80. package/src/ChatBlock/tests/withOnyxData.test.jsx +0 -81
  81. /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
- });