@eeacms/volto-eea-chatbot 2.0.1 → 2.0.3

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 (84) hide show
  1. package/.eslintrc.js +6 -6
  2. package/CHANGELOG.md +20 -0
  3. package/artifacts/ONYX_V3_INTEGRATION.md +34 -0
  4. package/jest-addon.config.js +2 -1
  5. package/package.json +1 -1
  6. package/src/ChatBlock/ChatBlockEdit.jsx +2 -1
  7. package/src/ChatBlock/chat/AIMessage.tsx +36 -16
  8. package/src/ChatBlock/chat/ChatMessage.tsx +1 -1
  9. package/src/ChatBlock/chat/ChatWindow.tsx +13 -11
  10. package/src/ChatBlock/chat/UserMessage.tsx +4 -4
  11. package/src/ChatBlock/components/AutoResizeTextarea.jsx +1 -1
  12. package/src/ChatBlock/components/ChatMessageFeedback.jsx +2 -2
  13. package/src/ChatBlock/components/EmptyState.jsx +1 -1
  14. package/src/ChatBlock/components/FeedbackModal.jsx +1 -1
  15. package/src/ChatBlock/components/HalloumiFeedback.jsx +2 -2
  16. package/src/ChatBlock/components/Source.jsx +2 -2
  17. package/src/ChatBlock/components/UserActionsToolbar.jsx +3 -3
  18. package/src/ChatBlock/components/WebResultIcon.tsx +2 -2
  19. package/src/ChatBlock/components/markdown/ClaimModal.jsx +3 -3
  20. package/src/ChatBlock/components/markdown/ClaimSegments.jsx +4 -4
  21. package/src/ChatBlock/components/markdown/{index.js → index.jsx} +1 -1
  22. package/src/ChatBlock/hooks/useChatController.ts +67 -14
  23. package/src/ChatBlock/hooks/useChatStreaming.ts +4 -4
  24. package/src/ChatBlock/hooks/useToolDisplayTiming.ts +2 -1
  25. package/src/ChatBlock/packets/MultiToolRenderer.tsx +86 -56
  26. package/src/ChatBlock/packets/RendererComponent.tsx +13 -5
  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 +14 -9
  31. package/src/ChatBlock/packets/renderers/ReasoningRenderer.tsx +6 -5
  32. package/src/ChatBlock/packets/renderers/SearchToolRenderer.tsx +30 -21
  33. package/src/ChatBlock/{schema.js → schema.jsx} +13 -0
  34. package/src/ChatBlock/services/messageProcessor.ts +72 -17
  35. package/src/ChatBlock/services/packetUtils.ts +13 -3
  36. package/src/ChatBlock/services/streamingService.ts +155 -68
  37. package/src/ChatBlock/types/streamingModels.ts +47 -2
  38. package/src/ChatBlock/utils/citations.ts +1 -1
  39. package/src/halloumi/filtering.test.js +199 -1
  40. package/src/middleware.js +18 -1
  41. package/src/middleware.test.js +14 -0
  42. package/src/ChatBlock/tests/AIMessage.test.jsx +0 -95
  43. package/src/ChatBlock/tests/AutoResizeTextarea.test.jsx +0 -49
  44. package/src/ChatBlock/tests/BlinkingDot.test.jsx +0 -71
  45. package/src/ChatBlock/tests/ChatMessage.test.jsx +0 -75
  46. package/src/ChatBlock/tests/ChatMessageFeedback.test.jsx +0 -73
  47. package/src/ChatBlock/tests/Citation.test.jsx +0 -107
  48. package/src/ChatBlock/tests/ClaimModal.test.jsx +0 -136
  49. package/src/ChatBlock/tests/ClaimSegments.test.jsx +0 -206
  50. package/src/ChatBlock/tests/CustomToolRenderer.test.jsx +0 -241
  51. package/src/ChatBlock/tests/EmptyState.test.jsx +0 -137
  52. package/src/ChatBlock/tests/FeedbackModal.test.jsx +0 -138
  53. package/src/ChatBlock/tests/FetchToolRenderer.test.jsx +0 -161
  54. package/src/ChatBlock/tests/HalloumiFeedback.test.jsx +0 -94
  55. package/src/ChatBlock/tests/ImageToolRenderer.test.jsx +0 -178
  56. package/src/ChatBlock/tests/MessageTextRenderer.test.jsx +0 -227
  57. package/src/ChatBlock/tests/MultiToolRenderer.test.jsx +0 -134
  58. package/src/ChatBlock/tests/QualityCheckToggle.test.jsx +0 -105
  59. package/src/ChatBlock/tests/ReasoningRenderer.test.jsx +0 -163
  60. package/src/ChatBlock/tests/RelatedQuestions.test.jsx +0 -215
  61. package/src/ChatBlock/tests/RenderClaimView.test.jsx +0 -191
  62. package/src/ChatBlock/tests/RendererComponent.test.jsx +0 -139
  63. package/src/ChatBlock/tests/SearchToolRenderer.test.jsx +0 -295
  64. package/src/ChatBlock/tests/Source.test.jsx +0 -79
  65. package/src/ChatBlock/tests/SourceChip.test.jsx +0 -108
  66. package/src/ChatBlock/tests/Spinner.test.jsx +0 -18
  67. package/src/ChatBlock/tests/UserActionsToolbar.test.jsx +0 -135
  68. package/src/ChatBlock/tests/UserMessage.test.jsx +0 -83
  69. package/src/ChatBlock/tests/WebResultIcon.test.jsx +0 -61
  70. package/src/ChatBlock/tests/citations.test.js +0 -114
  71. package/src/ChatBlock/tests/index.test.js +0 -51
  72. package/src/ChatBlock/tests/messageProcessor.test.jsx +0 -438
  73. package/src/ChatBlock/tests/packetUtils.test.js +0 -158
  74. package/src/ChatBlock/tests/schema.test.js +0 -166
  75. package/src/ChatBlock/tests/streamingService.test.js +0 -467
  76. package/src/ChatBlock/tests/useChatController.test.jsx +0 -268
  77. package/src/ChatBlock/tests/useChatStreaming.test.jsx +0 -163
  78. package/src/ChatBlock/tests/useDeepCompareMemoize.test.js +0 -107
  79. package/src/ChatBlock/tests/useMarked.test.jsx +0 -107
  80. package/src/ChatBlock/tests/useQualityMarkers.test.jsx +0 -150
  81. package/src/ChatBlock/tests/useScrollonStream.test.jsx +0 -121
  82. package/src/ChatBlock/tests/useToolDisplayTiming.test.jsx +0 -151
  83. package/src/ChatBlock/tests/utils.test.jsx +0 -241
  84. package/src/ChatBlock/tests/withOnyxData.test.jsx +0 -81
@@ -1,227 +0,0 @@
1
- import React from 'react';
2
- import renderer, { act } from 'react-test-renderer';
3
- import { MessageTextRenderer } from '../packets/renderers/MessageTextRenderer';
4
- import { PacketType } from '../types/streamingModels';
5
-
6
- // Mock AudioContext
7
- const mockClose = jest.fn();
8
- global.AudioContext = jest.fn().mockImplementation(() => ({
9
- close: mockClose,
10
- }));
11
-
12
- jest.mock('@loadable/component', () => {
13
- const loadable = () => {
14
- const MockMarkdown = ({ children }) => (
15
- <div data-testid="markdown">{children}</div>
16
- );
17
- return MockMarkdown;
18
- };
19
- loadable.lib = () => {
20
- const MockComponent = ({ children }) =>
21
- children ? children({ default: {} }) : null;
22
- return MockComponent;
23
- };
24
- return { __esModule: true, default: loadable };
25
- });
26
-
27
- describe('MessageTextRenderer', () => {
28
- const mockChildRenderer = (result) => (
29
- <div data-testid="renderer-result">
30
- <div data-testid="status">{result.status}</div>
31
- <div data-testid="content">{result.content}</div>
32
- </div>
33
- );
34
-
35
- const defaultMessage = {
36
- messageId: 1,
37
- nodeId: 1,
38
- message: 'Hello world',
39
- type: 'assistant',
40
- packets: [],
41
- files: [],
42
- toolCall: null,
43
- parentNodeId: null,
44
- };
45
-
46
- const defaultLibs = { remarkGfm: { default: [] } };
47
-
48
- it('renders message content without animation', () => {
49
- const packets = [
50
- {
51
- ind: 1,
52
- obj: {
53
- type: PacketType.MESSAGE_START,
54
- content: 'Hello',
55
- final_documents: null,
56
- },
57
- },
58
- { ind: 1, obj: { type: PacketType.MESSAGE_DELTA, content: ' world' } },
59
- { ind: 1, obj: { type: PacketType.MESSAGE_END } },
60
- { ind: 1, obj: { type: PacketType.STOP } },
61
- ];
62
-
63
- let component;
64
- act(() => {
65
- component = renderer.create(
66
- <MessageTextRenderer
67
- packets={packets}
68
- onComplete={jest.fn()}
69
- animate={false}
70
- stopPacketSeen={true}
71
- message={defaultMessage}
72
- libs={defaultLibs}
73
- >
74
- {mockChildRenderer}
75
- </MessageTextRenderer>,
76
- );
77
- });
78
- expect(component.toJSON()).toMatchSnapshot();
79
- });
80
-
81
- it('renders blinking dot when no content and no packets', () => {
82
- const emptyMessage = { ...defaultMessage, message: '' };
83
-
84
- let component;
85
- act(() => {
86
- component = renderer.create(
87
- <MessageTextRenderer
88
- packets={[]}
89
- onComplete={jest.fn()}
90
- animate={false}
91
- stopPacketSeen={false}
92
- message={emptyMessage}
93
- libs={defaultLibs}
94
- >
95
- {mockChildRenderer}
96
- </MessageTextRenderer>,
97
- );
98
- });
99
- expect(component.toJSON()).toMatchSnapshot();
100
- });
101
-
102
- it('calls onComplete when stream is finished', () => {
103
- const onComplete = jest.fn();
104
- const packets = [
105
- {
106
- ind: 1,
107
- obj: {
108
- type: PacketType.MESSAGE_START,
109
- content: 'Hi',
110
- final_documents: null,
111
- },
112
- },
113
- { ind: 1, obj: { type: PacketType.MESSAGE_END } },
114
- { ind: 1, obj: { type: PacketType.SECTION_END } },
115
- ];
116
-
117
- act(() => {
118
- renderer.create(
119
- <MessageTextRenderer
120
- packets={packets}
121
- onComplete={onComplete}
122
- animate={false}
123
- stopPacketSeen={true}
124
- message={defaultMessage}
125
- libs={defaultLibs}
126
- >
127
- {mockChildRenderer}
128
- </MessageTextRenderer>,
129
- );
130
- });
131
-
132
- expect(onComplete).toHaveBeenCalled();
133
- });
134
-
135
- it('shows cursor when stream is not complete', () => {
136
- const packets = [
137
- {
138
- ind: 1,
139
- obj: {
140
- type: PacketType.MESSAGE_START,
141
- content: 'Starting...',
142
- final_documents: null,
143
- },
144
- },
145
- ];
146
-
147
- let component;
148
- act(() => {
149
- component = renderer.create(
150
- <MessageTextRenderer
151
- packets={packets}
152
- onComplete={jest.fn()}
153
- animate={false}
154
- stopPacketSeen={false}
155
- message={{ ...defaultMessage, message: 'Starting...' }}
156
- libs={defaultLibs}
157
- >
158
- {mockChildRenderer}
159
- </MessageTextRenderer>,
160
- );
161
- });
162
- expect(component.toJSON()).toMatchSnapshot();
163
- });
164
-
165
- it('renders with remarkGfm plugin when available', () => {
166
- const packets = [
167
- {
168
- ind: 1,
169
- obj: {
170
- type: PacketType.MESSAGE_START,
171
- content: 'test',
172
- final_documents: null,
173
- },
174
- },
175
- { ind: 1, obj: { type: PacketType.MESSAGE_END } },
176
- { ind: 1, obj: { type: PacketType.STOP } },
177
- ];
178
-
179
- let component;
180
- act(() => {
181
- component = renderer.create(
182
- <MessageTextRenderer
183
- packets={packets}
184
- onComplete={jest.fn()}
185
- animate={false}
186
- stopPacketSeen={true}
187
- message={defaultMessage}
188
- libs={{ remarkGfm: { default: () => {} } }}
189
- >
190
- {mockChildRenderer}
191
- </MessageTextRenderer>,
192
- );
193
- });
194
- expect(component.toJSON()).toMatchSnapshot();
195
- });
196
-
197
- it('renders with no remarkGfm', () => {
198
- const packets = [
199
- {
200
- ind: 1,
201
- obj: {
202
- type: PacketType.MESSAGE_START,
203
- content: 'test',
204
- final_documents: null,
205
- },
206
- },
207
- { ind: 1, obj: { type: PacketType.STOP } },
208
- ];
209
-
210
- let component;
211
- act(() => {
212
- component = renderer.create(
213
- <MessageTextRenderer
214
- packets={packets}
215
- onComplete={jest.fn()}
216
- animate={false}
217
- stopPacketSeen={true}
218
- message={defaultMessage}
219
- libs={{ remarkGfm: null }}
220
- >
221
- {mockChildRenderer}
222
- </MessageTextRenderer>,
223
- );
224
- });
225
- expect(component.toJSON()).toMatchSnapshot();
226
- });
227
- });
@@ -1,134 +0,0 @@
1
- import React from 'react';
2
- import renderer, { act } from 'react-test-renderer';
3
- import { MultiToolRenderer } from '../packets/MultiToolRenderer';
4
- import { PacketType } from '../types/streamingModels';
5
-
6
- jest.mock('@loadable/component', () => {
7
- const loadable = () => {
8
- const MockComponent = ({ children }) => (
9
- <div data-testid="loadable">{children}</div>
10
- );
11
- return MockComponent;
12
- };
13
- loadable.lib = () => {
14
- const MockComponent = ({ children }) =>
15
- children ? children({ default: {} }) : null;
16
- return MockComponent;
17
- };
18
- return { __esModule: true, default: loadable };
19
- });
20
-
21
- // Mock SVGIcon
22
- jest.mock('../components/Icon', () => {
23
- return ({ name, size }) => <span data-icon={name} data-size={size} />;
24
- });
25
-
26
- // Mock SVG imports
27
- jest.mock('../../icons/done.svg', () => 'done-icon');
28
- jest.mock('../../icons/chevron.svg', () => 'chevron-icon');
29
-
30
- describe('MultiToolRenderer', () => {
31
- const defaultMessage = {
32
- messageId: 1,
33
- nodeId: 1,
34
- message: 'test',
35
- type: 'assistant',
36
- packets: [],
37
- files: [],
38
- toolCall: null,
39
- parentNodeId: null,
40
- isFinalMessageComing: false,
41
- isComplete: false,
42
- };
43
-
44
- const defaultLibs = { remarkGfm: { default: [] } };
45
-
46
- it('returns null when no tool groups match showTools filter', () => {
47
- const toolGroups = [
48
- {
49
- ind: 1,
50
- packets: [
51
- { ind: 1, obj: { type: PacketType.IMAGE_GENERATION_TOOL_START } },
52
- ],
53
- },
54
- ];
55
-
56
- const component = renderer.create(
57
- <MultiToolRenderer
58
- toolGroups={toolGroups}
59
- showTools={[PacketType.SEARCH_TOOL_START]}
60
- message={defaultMessage}
61
- libs={defaultLibs}
62
- />,
63
- );
64
- expect(component.toJSON()).toBeNull();
65
- });
66
-
67
- it('returns null for empty tool groups', () => {
68
- const component = renderer.create(
69
- <MultiToolRenderer
70
- toolGroups={[]}
71
- message={defaultMessage}
72
- libs={defaultLibs}
73
- />,
74
- );
75
- expect(component.toJSON()).toBeNull();
76
- });
77
-
78
- it('renders search tool groups', () => {
79
- const toolGroups = [
80
- {
81
- ind: 1,
82
- packets: [
83
- { ind: 1, obj: { type: PacketType.SEARCH_TOOL_START } },
84
- { ind: 1, obj: { type: PacketType.SECTION_END } },
85
- ],
86
- },
87
- ];
88
-
89
- let component;
90
- act(() => {
91
- component = renderer.create(
92
- <MultiToolRenderer
93
- toolGroups={toolGroups}
94
- showTools={[PacketType.SEARCH_TOOL_START]}
95
- message={defaultMessage}
96
- libs={defaultLibs}
97
- />,
98
- );
99
- });
100
- expect(component.toJSON()).toMatchSnapshot();
101
- });
102
-
103
- it('renders multiple tool groups', () => {
104
- const toolGroups = [
105
- {
106
- ind: 1,
107
- packets: [
108
- { ind: 1, obj: { type: PacketType.SEARCH_TOOL_START } },
109
- { ind: 1, obj: { type: PacketType.SECTION_END } },
110
- ],
111
- },
112
- {
113
- ind: 2,
114
- packets: [
115
- { ind: 2, obj: { type: PacketType.SEARCH_TOOL_START } },
116
- { ind: 2, obj: { type: PacketType.SECTION_END } },
117
- ],
118
- },
119
- ];
120
-
121
- let component;
122
- act(() => {
123
- component = renderer.create(
124
- <MultiToolRenderer
125
- toolGroups={toolGroups}
126
- showTools={[PacketType.SEARCH_TOOL_START]}
127
- message={defaultMessage}
128
- libs={defaultLibs}
129
- />,
130
- );
131
- });
132
- expect(component.toJSON()).toMatchSnapshot();
133
- });
134
- });
@@ -1,105 +0,0 @@
1
- import React from 'react';
2
- import { render, fireEvent } from '@testing-library/react';
3
- import '@testing-library/jest-dom';
4
- import QualityCheckToggle from '../components/QualityCheckToggle';
5
-
6
- describe('QualityCheckToggle', () => {
7
- const mockSetEnabled = jest.fn();
8
-
9
- beforeEach(() => {
10
- jest.clearAllMocks();
11
- });
12
-
13
- it('renders correctly', () => {
14
- const { container } = render(
15
- <QualityCheckToggle
16
- isEditMode={false}
17
- enabled={true}
18
- setEnabled={mockSetEnabled}
19
- />,
20
- );
21
-
22
- expect(
23
- container.querySelector('.quality-check-toggle'),
24
- ).toBeInTheDocument();
25
- });
26
-
27
- it('renders checkbox with correct label', () => {
28
- const { getByText } = render(
29
- <QualityCheckToggle
30
- isEditMode={false}
31
- enabled={true}
32
- setEnabled={mockSetEnabled}
33
- />,
34
- );
35
-
36
- expect(getByText('Fact-check AI answer')).toBeInTheDocument();
37
- });
38
-
39
- it('checkbox is checked when enabled is true', () => {
40
- const { container } = render(
41
- <QualityCheckToggle
42
- isEditMode={false}
43
- enabled={true}
44
- setEnabled={mockSetEnabled}
45
- />,
46
- );
47
-
48
- const checkbox = container.querySelector('input[type="checkbox"]');
49
- expect(checkbox.checked).toBe(true);
50
- });
51
-
52
- it('checkbox is unchecked when enabled is false', () => {
53
- const { container } = render(
54
- <QualityCheckToggle
55
- isEditMode={false}
56
- enabled={false}
57
- setEnabled={mockSetEnabled}
58
- />,
59
- );
60
-
61
- const checkbox = container.querySelector('input[type="checkbox"]');
62
- expect(checkbox.checked).toBe(false);
63
- });
64
-
65
- it('checkbox is disabled in edit mode', () => {
66
- const { container } = render(
67
- <QualityCheckToggle
68
- isEditMode={true}
69
- enabled={true}
70
- setEnabled={mockSetEnabled}
71
- />,
72
- );
73
-
74
- const checkbox = container.querySelector('input[type="checkbox"]');
75
- expect(checkbox.disabled).toBe(true);
76
- });
77
-
78
- it('checkbox is enabled when not in edit mode', () => {
79
- const { container } = render(
80
- <QualityCheckToggle
81
- isEditMode={false}
82
- enabled={true}
83
- setEnabled={mockSetEnabled}
84
- />,
85
- );
86
-
87
- const checkbox = container.querySelector('input[type="checkbox"]');
88
- expect(checkbox.disabled).toBe(false);
89
- });
90
-
91
- it('calls setEnabled when checkbox is changed', () => {
92
- const { container } = render(
93
- <QualityCheckToggle
94
- isEditMode={false}
95
- enabled={true}
96
- setEnabled={mockSetEnabled}
97
- />,
98
- );
99
-
100
- const checkbox = container.querySelector('input[type="checkbox"]');
101
- fireEvent.click(checkbox);
102
-
103
- expect(mockSetEnabled).toHaveBeenCalled();
104
- });
105
- });
@@ -1,163 +0,0 @@
1
- import React from 'react';
2
- import renderer, { act } from 'react-test-renderer';
3
- import { ReasoningRenderer } from '../packets/renderers/ReasoningRenderer';
4
- import { PacketType } from '../types/streamingModels';
5
-
6
- jest.mock('@loadable/component', () => {
7
- const loadable = () => {
8
- const MockMarkdown = ({ children }) => (
9
- <div data-testid="markdown">{children}</div>
10
- );
11
- return MockMarkdown;
12
- };
13
- loadable.lib = () => {
14
- const MockComponent = ({ children }) =>
15
- children ? children({ default: {} }) : null;
16
- return MockComponent;
17
- };
18
- return { __esModule: true, default: loadable };
19
- });
20
-
21
- describe('ReasoningRenderer', () => {
22
- const mockChildRenderer = (result) => (
23
- <div data-testid="renderer-result">
24
- <div data-testid="status">{result.status}</div>
25
- <div data-testid="content">{result.content}</div>
26
- </div>
27
- );
28
-
29
- const defaultMessage = {
30
- messageId: 1,
31
- nodeId: 1,
32
- message: 'test',
33
- type: 'assistant',
34
- packets: [],
35
- files: [],
36
- toolCall: null,
37
- parentNodeId: null,
38
- };
39
-
40
- const defaultLibs = { remarkGfm: { default: [] } };
41
-
42
- it('renders empty content when no packets', () => {
43
- const component = renderer.create(
44
- <ReasoningRenderer
45
- packets={[]}
46
- onComplete={jest.fn()}
47
- animate={false}
48
- stopPacketSeen={false}
49
- message={defaultMessage}
50
- libs={defaultLibs}
51
- >
52
- {mockChildRenderer}
53
- </ReasoningRenderer>,
54
- );
55
- expect(component.toJSON()).toMatchSnapshot();
56
- });
57
-
58
- it('renders thinking status when reasoning has started', () => {
59
- const packets = [
60
- { ind: 1, obj: { type: PacketType.REASONING_START } },
61
- {
62
- ind: 1,
63
- obj: { type: PacketType.REASONING_DELTA, reasoning: 'Let me think...' },
64
- },
65
- ];
66
-
67
- const component = renderer.create(
68
- <ReasoningRenderer
69
- packets={packets}
70
- onComplete={jest.fn()}
71
- animate={false}
72
- stopPacketSeen={false}
73
- message={defaultMessage}
74
- libs={defaultLibs}
75
- >
76
- {mockChildRenderer}
77
- </ReasoningRenderer>,
78
- );
79
- expect(component.toJSON()).toMatchSnapshot();
80
- });
81
-
82
- it('calls onComplete when reasoning ends without animation', () => {
83
- const onComplete = jest.fn();
84
- const packets = [
85
- { ind: 1, obj: { type: PacketType.REASONING_START } },
86
- {
87
- ind: 1,
88
- obj: { type: PacketType.REASONING_DELTA, reasoning: 'Thinking...' },
89
- },
90
- { ind: 1, obj: { type: PacketType.SECTION_END } },
91
- ];
92
-
93
- act(() => {
94
- renderer.create(
95
- <ReasoningRenderer
96
- packets={packets}
97
- onComplete={onComplete}
98
- animate={false}
99
- stopPacketSeen={false}
100
- message={defaultMessage}
101
- libs={defaultLibs}
102
- >
103
- {mockChildRenderer}
104
- </ReasoningRenderer>,
105
- );
106
- });
107
-
108
- expect(onComplete).toHaveBeenCalled();
109
- });
110
-
111
- it('renders with REASONING_END packet type', () => {
112
- const packets = [
113
- { ind: 1, obj: { type: PacketType.REASONING_START } },
114
- {
115
- ind: 1,
116
- obj: { type: PacketType.REASONING_DELTA, reasoning: 'Analysis' },
117
- },
118
- { ind: 1, obj: { type: PacketType.REASONING_END } },
119
- ];
120
-
121
- const component = renderer.create(
122
- <ReasoningRenderer
123
- packets={packets}
124
- onComplete={jest.fn()}
125
- animate={false}
126
- stopPacketSeen={false}
127
- message={defaultMessage}
128
- libs={defaultLibs}
129
- >
130
- {mockChildRenderer}
131
- </ReasoningRenderer>,
132
- );
133
- expect(component.toJSON()).toMatchSnapshot();
134
- });
135
-
136
- it('concatenates multiple reasoning deltas', () => {
137
- const packets = [
138
- { ind: 1, obj: { type: PacketType.REASONING_START } },
139
- {
140
- ind: 1,
141
- obj: { type: PacketType.REASONING_DELTA, reasoning: 'First ' },
142
- },
143
- {
144
- ind: 1,
145
- obj: { type: PacketType.REASONING_DELTA, reasoning: 'second' },
146
- },
147
- ];
148
-
149
- const component = renderer.create(
150
- <ReasoningRenderer
151
- packets={packets}
152
- onComplete={jest.fn()}
153
- animate={false}
154
- stopPacketSeen={false}
155
- message={defaultMessage}
156
- libs={defaultLibs}
157
- >
158
- {mockChildRenderer}
159
- </ReasoningRenderer>,
160
- );
161
- expect(component.toJSON()).toMatchSnapshot();
162
- });
163
- });