@bernierllc/chat-suite 1.0.0

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 (105) hide show
  1. package/.eslintrc.js +26 -0
  2. package/README.md +542 -0
  3. package/__tests__/integration/ChatSuite.test.ts +235 -0
  4. package/__tests__/unit/ConfigManager.test.ts +122 -0
  5. package/__tests__/unit/MessageOrchestrator.test.ts +223 -0
  6. package/__tests__/unit/UserManager.test.ts +208 -0
  7. package/dist/ChatSuite.d.ts +76 -0
  8. package/dist/ChatSuite.d.ts.map +1 -0
  9. package/dist/ChatSuite.js +273 -0
  10. package/dist/index.d.ts +7 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +37 -0
  13. package/dist/neverhub/discovery.d.ts +40 -0
  14. package/dist/neverhub/discovery.d.ts.map +1 -0
  15. package/dist/neverhub/discovery.js +106 -0
  16. package/dist/neverhub/event-handlers.d.ts +38 -0
  17. package/dist/neverhub/event-handlers.d.ts.map +1 -0
  18. package/dist/neverhub/event-handlers.js +125 -0
  19. package/dist/neverhub/index.d.ts +4 -0
  20. package/dist/neverhub/index.d.ts.map +1 -0
  21. package/dist/neverhub/index.js +26 -0
  22. package/dist/neverhub/service-registration.d.ts +29 -0
  23. package/dist/neverhub/service-registration.d.ts.map +1 -0
  24. package/dist/neverhub/service-registration.js +66 -0
  25. package/dist/providers/ChatKitProvider.d.ts +53 -0
  26. package/dist/providers/ChatKitProvider.d.ts.map +1 -0
  27. package/dist/providers/ChatKitProvider.js +167 -0
  28. package/dist/providers/ExternalProviders.d.ts +101 -0
  29. package/dist/providers/ExternalProviders.d.ts.map +1 -0
  30. package/dist/providers/ExternalProviders.js +153 -0
  31. package/dist/providers/index.d.ts +3 -0
  32. package/dist/providers/index.d.ts.map +1 -0
  33. package/dist/providers/index.js +25 -0
  34. package/dist/services/ConfigManager.d.ts +50 -0
  35. package/dist/services/ConfigManager.d.ts.map +1 -0
  36. package/dist/services/ConfigManager.js +95 -0
  37. package/dist/services/HealthMonitor.d.ts +58 -0
  38. package/dist/services/HealthMonitor.d.ts.map +1 -0
  39. package/dist/services/HealthMonitor.js +148 -0
  40. package/dist/services/MessageOrchestrator.d.ts +63 -0
  41. package/dist/services/MessageOrchestrator.d.ts.map +1 -0
  42. package/dist/services/MessageOrchestrator.js +212 -0
  43. package/dist/services/ProviderManager.d.ts +83 -0
  44. package/dist/services/ProviderManager.d.ts.map +1 -0
  45. package/dist/services/ProviderManager.js +204 -0
  46. package/dist/services/UserManager.d.ts +61 -0
  47. package/dist/services/UserManager.d.ts.map +1 -0
  48. package/dist/services/UserManager.js +141 -0
  49. package/dist/services/index.d.ts +6 -0
  50. package/dist/services/index.d.ts.map +1 -0
  51. package/dist/services/index.js +28 -0
  52. package/dist/types/index.d.ts +4 -0
  53. package/dist/types/index.d.ts.map +1 -0
  54. package/dist/types/index.js +26 -0
  55. package/dist/types/message-types.d.ts +80 -0
  56. package/dist/types/message-types.d.ts.map +1 -0
  57. package/dist/types/message-types.js +32 -0
  58. package/dist/types/provider-types.d.ts +96 -0
  59. package/dist/types/provider-types.d.ts.map +1 -0
  60. package/dist/types/provider-types.js +9 -0
  61. package/dist/types/suite-types.d.ts +101 -0
  62. package/dist/types/suite-types.d.ts.map +1 -0
  63. package/dist/types/suite-types.js +9 -0
  64. package/dist/utils/config-inheritance.d.ts +24 -0
  65. package/dist/utils/config-inheritance.d.ts.map +1 -0
  66. package/dist/utils/config-inheritance.js +167 -0
  67. package/dist/utils/error-handling.d.ts +37 -0
  68. package/dist/utils/error-handling.d.ts.map +1 -0
  69. package/dist/utils/error-handling.js +102 -0
  70. package/dist/utils/index.d.ts +5 -0
  71. package/dist/utils/index.d.ts.map +1 -0
  72. package/dist/utils/index.js +27 -0
  73. package/dist/utils/message-bridge.d.ts +68 -0
  74. package/dist/utils/message-bridge.d.ts.map +1 -0
  75. package/dist/utils/message-bridge.js +126 -0
  76. package/dist/utils/user-mapping.d.ts +63 -0
  77. package/dist/utils/user-mapping.d.ts.map +1 -0
  78. package/dist/utils/user-mapping.js +110 -0
  79. package/jest.config.cjs +30 -0
  80. package/package.json +67 -0
  81. package/src/ChatSuite.ts +347 -0
  82. package/src/index.ts +25 -0
  83. package/src/neverhub/discovery.ts +137 -0
  84. package/src/neverhub/event-handlers.ts +141 -0
  85. package/src/neverhub/index.ts +11 -0
  86. package/src/neverhub/service-registration.ts +89 -0
  87. package/src/providers/ChatKitProvider.ts +193 -0
  88. package/src/providers/ExternalProviders.ts +171 -0
  89. package/src/providers/index.ts +10 -0
  90. package/src/services/ConfigManager.ts +112 -0
  91. package/src/services/HealthMonitor.ts +169 -0
  92. package/src/services/MessageOrchestrator.ts +271 -0
  93. package/src/services/ProviderManager.ts +247 -0
  94. package/src/services/UserManager.ts +176 -0
  95. package/src/services/index.ts +13 -0
  96. package/src/types/index.ts +11 -0
  97. package/src/types/message-types.ts +94 -0
  98. package/src/types/provider-types.ts +116 -0
  99. package/src/types/suite-types.ts +117 -0
  100. package/src/utils/config-inheritance.ts +189 -0
  101. package/src/utils/error-handling.ts +114 -0
  102. package/src/utils/index.ts +12 -0
  103. package/src/utils/message-bridge.ts +164 -0
  104. package/src/utils/user-mapping.ts +132 -0
  105. package/tsconfig.json +31 -0
@@ -0,0 +1,235 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+
9
+ import { ChatSuite } from '../../src/ChatSuite';
10
+ import { MessagePriority } from '../../src/types';
11
+
12
+ describe('ChatSuite Integration', () => {
13
+ describe('initialization', () => {
14
+ it('should initialize with default configuration', async () => {
15
+ const suite = new ChatSuite();
16
+
17
+ const result = await suite.initialize();
18
+
19
+ expect(result.success).toBe(true);
20
+ expect(result.providersInitialized).toContain('chatkit');
21
+ expect(suite.isInitialized()).toBe(true);
22
+ });
23
+
24
+ it('should initialize with custom configuration', async () => {
25
+ const suite = new ChatSuite({
26
+ analytics: { enabled: false }
27
+ });
28
+
29
+ const result = await suite.initialize();
30
+
31
+ expect(result.success).toBe(true);
32
+ expect(result.analyticsEnabled).toBe(false);
33
+ });
34
+
35
+ it('should not connect to NeverHub when disabled', async () => {
36
+ const suite = new ChatSuite({
37
+ neverhub: { enabled: false, serviceName: '', capabilities: [], dependencies: [] }
38
+ });
39
+
40
+ await suite.initialize();
41
+
42
+ expect(suite.isNeverHubConnected()).toBe(false);
43
+ });
44
+ });
45
+
46
+ describe('message operations', () => {
47
+ let suite: ChatSuite;
48
+
49
+ beforeEach(async () => {
50
+ suite = new ChatSuite();
51
+ await suite.initialize();
52
+ });
53
+
54
+ afterEach(async () => {
55
+ await suite.shutdown();
56
+ });
57
+
58
+ it('should send a message through ChatKit', async () => {
59
+ const result = await suite.sendMessage('chatkit', {
60
+ content: 'Test message',
61
+ userId: 'user123'
62
+ });
63
+
64
+ expect(result.success).toBe(true);
65
+ expect(result.data?.provider).toBe('chatkit');
66
+ });
67
+
68
+ it('should broadcast a message', async () => {
69
+ const result = await suite.broadcastMessage({
70
+ content: 'Broadcast test',
71
+ platforms: ['chatkit'],
72
+ priority: MessagePriority.HIGH
73
+ });
74
+
75
+ expect(result.success).toBe(true);
76
+ expect(result.data).toBeDefined();
77
+ });
78
+
79
+ it('should fail to send when not initialized', async () => {
80
+ const uninitializedSuite = new ChatSuite();
81
+
82
+ const result = await uninitializedSuite.sendMessage('chatkit', {
83
+ content: 'Test'
84
+ });
85
+
86
+ expect(result.success).toBe(false);
87
+ expect(result.error).toContain('not initialized');
88
+ });
89
+ });
90
+
91
+ describe('health monitoring', () => {
92
+ let suite: ChatSuite;
93
+
94
+ beforeEach(async () => {
95
+ suite = new ChatSuite();
96
+ await suite.initialize();
97
+ });
98
+
99
+ afterEach(async () => {
100
+ await suite.shutdown();
101
+ });
102
+
103
+ it('should report health status', async () => {
104
+ const health = await suite.getHealth();
105
+
106
+ expect(health.status).toBeDefined();
107
+ expect(health.providers).toBeDefined();
108
+ expect(health.timestamp).toBeInstanceOf(Date);
109
+ });
110
+
111
+ it('should include provider health information', async () => {
112
+ const health = await suite.getHealth();
113
+
114
+ expect(health.providers.chatkit).toBeDefined();
115
+ expect(health.providers.chatkit.status).toBeDefined();
116
+ });
117
+ });
118
+
119
+ describe('user management', () => {
120
+ let suite: ChatSuite;
121
+
122
+ beforeEach(async () => {
123
+ suite = new ChatSuite();
124
+ await suite.initialize();
125
+ });
126
+
127
+ afterEach(async () => {
128
+ await suite.shutdown();
129
+ });
130
+
131
+ it('should provide access to user manager', () => {
132
+ const userManager = suite.getUserManager();
133
+
134
+ expect(userManager).toBeDefined();
135
+ expect(typeof userManager.registerUser).toBe('function');
136
+ });
137
+
138
+ it('should register and retrieve users', () => {
139
+ const userManager = suite.getUserManager();
140
+
141
+ const result = userManager.registerUser({
142
+ provider: 'chatkit',
143
+ platformUserId: 'user123',
144
+ displayName: 'Test User'
145
+ });
146
+
147
+ expect(result.success).toBe(true);
148
+ expect(result.data?.displayName).toBe('Test User');
149
+ });
150
+ });
151
+
152
+ describe('configuration management', () => {
153
+ let suite: ChatSuite;
154
+
155
+ beforeEach(async () => {
156
+ suite = new ChatSuite();
157
+ await suite.initialize();
158
+ });
159
+
160
+ afterEach(async () => {
161
+ await suite.shutdown();
162
+ });
163
+
164
+ it('should provide access to config manager', () => {
165
+ const configManager = suite.getConfigManager();
166
+
167
+ expect(configManager).toBeDefined();
168
+ expect(typeof configManager.getConfig).toBe('function');
169
+ });
170
+
171
+ it('should allow configuration updates', () => {
172
+ const configManager = suite.getConfigManager();
173
+
174
+ configManager.updateConfig({
175
+ analytics: { enabled: false }
176
+ });
177
+
178
+ const config = configManager.getConfig();
179
+ expect(config.analytics?.enabled).toBe(false);
180
+ });
181
+ });
182
+
183
+ describe('lifecycle management', () => {
184
+ it('should shutdown gracefully', async () => {
185
+ const suite = new ChatSuite();
186
+ await suite.initialize();
187
+
188
+ expect(suite.isInitialized()).toBe(true);
189
+
190
+ await suite.shutdown();
191
+
192
+ expect(suite.isInitialized()).toBe(false);
193
+ });
194
+
195
+ it('should allow reinitialization after shutdown', async () => {
196
+ const suite = new ChatSuite();
197
+ await suite.initialize();
198
+ await suite.shutdown();
199
+
200
+ const result = await suite.initialize();
201
+
202
+ expect(result.success).toBe(true);
203
+ expect(suite.isInitialized()).toBe(true);
204
+
205
+ await suite.shutdown();
206
+ });
207
+ });
208
+
209
+ describe('provider management', () => {
210
+ let suite: ChatSuite;
211
+
212
+ beforeEach(async () => {
213
+ suite = new ChatSuite();
214
+ await suite.initialize();
215
+ });
216
+
217
+ afterEach(async () => {
218
+ await suite.shutdown();
219
+ });
220
+
221
+ it('should provide access to provider manager', () => {
222
+ const providerManager = suite.getProviderManager();
223
+
224
+ expect(providerManager).toBeDefined();
225
+ expect(typeof providerManager.getProvider).toBe('function');
226
+ });
227
+
228
+ it('should have ChatKit provider initialized', () => {
229
+ const providerManager = suite.getProviderManager();
230
+ const isInitialized = providerManager.isInitialized('chatkit');
231
+
232
+ expect(isInitialized).toBe(true);
233
+ });
234
+ });
235
+ });
@@ -0,0 +1,122 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+
9
+ import { ConfigManager } from '../../src/services/ConfigManager';
10
+ import { ChatSuiteError } from '../../src/utils/error-handling';
11
+
12
+ describe('ConfigManager', () => {
13
+ describe('initialization', () => {
14
+ it('should initialize with default configuration', () => {
15
+ const manager = new ConfigManager();
16
+ const config = manager.getConfig();
17
+
18
+ expect(config.enabled).toBe(true);
19
+ expect(config.providers.chatkit?.enabled).toBe(true);
20
+ });
21
+
22
+ it('should merge custom configuration with defaults', () => {
23
+ const manager = new ConfigManager({
24
+ aiRouting: { enabled: false }
25
+ });
26
+
27
+ const config = manager.getConfig();
28
+ expect(config.aiRouting?.enabled).toBe(false);
29
+ expect(config.providers.chatkit?.enabled).toBe(true);
30
+ });
31
+
32
+ it('should throw error for invalid configuration', () => {
33
+ expect(() => {
34
+ new ConfigManager({
35
+ providers: {} // No providers enabled
36
+ });
37
+ }).toThrow(ChatSuiteError);
38
+ });
39
+ });
40
+
41
+ describe('configuration updates', () => {
42
+ it('should update configuration', () => {
43
+ const manager = new ConfigManager();
44
+
45
+ manager.updateConfig({
46
+ analytics: { enabled: false }
47
+ });
48
+
49
+ expect(manager.get('analytics')?.enabled).toBe(false);
50
+ });
51
+
52
+ it('should validate configuration on update', () => {
53
+ const manager = new ConfigManager();
54
+
55
+ expect(() => {
56
+ manager.updateConfig({
57
+ providers: {} // Invalid: no providers
58
+ });
59
+ }).toThrow(ChatSuiteError);
60
+ });
61
+ });
62
+
63
+ describe('overrides', () => {
64
+ it('should set and get overrides', () => {
65
+ const manager = new ConfigManager();
66
+
67
+ manager.setOverride('customKey', 'customValue');
68
+ expect(manager.getOverride('customKey')).toBe('customValue');
69
+ });
70
+
71
+ it('should clear overrides', () => {
72
+ const manager = new ConfigManager();
73
+
74
+ manager.setOverride('key1', 'value1');
75
+ manager.setOverride('key2', 'value2');
76
+ manager.clearOverrides();
77
+
78
+ expect(manager.getOverride('key1')).toBeUndefined();
79
+ expect(manager.getOverride('key2')).toBeUndefined();
80
+ });
81
+ });
82
+
83
+ describe('JSON serialization', () => {
84
+ it('should export configuration as JSON', () => {
85
+ const manager = new ConfigManager();
86
+ const json = manager.toJSON();
87
+
88
+ expect(() => JSON.parse(json)).not.toThrow();
89
+ });
90
+
91
+ it('should import configuration from JSON', () => {
92
+ const manager = new ConfigManager();
93
+ const json = JSON.stringify({
94
+ analytics: { enabled: false }
95
+ });
96
+
97
+ manager.fromJSON(json);
98
+ expect(manager.get('analytics')?.enabled).toBe(false);
99
+ });
100
+
101
+ it('should throw error for invalid JSON', () => {
102
+ const manager = new ConfigManager();
103
+
104
+ expect(() => {
105
+ manager.fromJSON('invalid json');
106
+ }).toThrow(ChatSuiteError);
107
+ });
108
+ });
109
+
110
+ describe('reset', () => {
111
+ it('should reset to default configuration', () => {
112
+ const manager = new ConfigManager({
113
+ analytics: { enabled: false }
114
+ });
115
+
116
+ manager.reset();
117
+
118
+ const config = manager.getConfig();
119
+ expect(config.analytics?.enabled).toBe(true);
120
+ });
121
+ });
122
+ });
@@ -0,0 +1,223 @@
1
+ /*
2
+ Copyright (c) 2025 Bernier LLC
3
+
4
+ This file is licensed to the client under a limited-use license.
5
+ The client may use and modify this code *only within the scope of the project it was delivered for*.
6
+ Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
7
+ */
8
+
9
+ import { MessageOrchestrator } from '../../src/services/MessageOrchestrator';
10
+ import { MessagePriority, MessageStatus } from '../../src/types';
11
+ import type { Provider, ProviderMessage } from '../../src/types';
12
+
13
+ // Mock provider for testing
14
+ class MockProvider implements Provider {
15
+ public readonly type = 'chatkit' as const;
16
+ public readonly name = 'mock-provider';
17
+ private _initialized = false;
18
+
19
+ public async initialize(): Promise<void> {
20
+ this._initialized = true;
21
+ }
22
+
23
+ public isInitialized(): boolean {
24
+ return this._initialized;
25
+ }
26
+
27
+ public async sendMessage(message: ProviderMessage) {
28
+ return {
29
+ success: true,
30
+ messageId: 'msg123',
31
+ timestamp: new Date(),
32
+ provider: this.type
33
+ };
34
+ }
35
+
36
+ public async getHealth() {
37
+ return {
38
+ status: 'healthy' as const,
39
+ lastCheck: new Date(),
40
+ errorCount: 0
41
+ };
42
+ }
43
+
44
+ public async shutdown(): Promise<void> {
45
+ this._initialized = false;
46
+ }
47
+ }
48
+
49
+ describe('MessageOrchestrator', () => {
50
+ let orchestrator: MessageOrchestrator;
51
+ let mockProvider: MockProvider;
52
+
53
+ beforeEach(async () => {
54
+ orchestrator = new MessageOrchestrator();
55
+ mockProvider = new MockProvider();
56
+ await mockProvider.initialize();
57
+ });
58
+
59
+ describe('message sending', () => {
60
+ it('should send a message through a provider', async () => {
61
+ const result = await orchestrator.sendMessage(mockProvider, {
62
+ content: 'Test message'
63
+ });
64
+
65
+ expect(result.success).toBe(true);
66
+ expect(result.data?.messageId).toBe('msg123');
67
+ });
68
+
69
+ it('should fail if provider not initialized', async () => {
70
+ const uninitializedProvider = new MockProvider();
71
+
72
+ const result = await orchestrator.sendMessage(uninitializedProvider, {
73
+ content: 'Test message'
74
+ });
75
+
76
+ expect(result.success).toBe(false);
77
+ expect(result.error).toContain('not initialized');
78
+ });
79
+ });
80
+
81
+ describe('message broadcasting', () => {
82
+ it('should broadcast to multiple providers', async () => {
83
+ const providers = new Map();
84
+ providers.set('chatkit', mockProvider);
85
+
86
+ const result = await orchestrator.broadcastMessage(providers, {
87
+ content: 'Broadcast message',
88
+ platforms: ['chatkit']
89
+ });
90
+
91
+ expect(result.success).toBe(true);
92
+ expect(result.data).toHaveLength(1);
93
+ });
94
+
95
+ it('should fail if no valid providers', async () => {
96
+ const result = await orchestrator.broadcastMessage(
97
+ new Map(),
98
+ {
99
+ content: 'Test',
100
+ platforms: ['slack']
101
+ }
102
+ );
103
+
104
+ expect(result.success).toBe(false);
105
+ expect(result.error).toContain('No valid providers');
106
+ });
107
+ });
108
+
109
+ describe('message tracking', () => {
110
+ it('should track broadcast messages', async () => {
111
+ const providers = new Map();
112
+ providers.set('chatkit', mockProvider);
113
+
114
+ await orchestrator.broadcastMessage(providers, {
115
+ content: 'Test',
116
+ platforms: ['chatkit'],
117
+ priority: MessagePriority.HIGH
118
+ });
119
+
120
+ const messages = orchestrator.getAllMessages();
121
+ expect(messages.length).toBeGreaterThan(0);
122
+ expect(messages[0].priority).toBe(MessagePriority.HIGH);
123
+ });
124
+
125
+ it('should get message by ID', async () => {
126
+ const providers = new Map();
127
+ providers.set('chatkit', mockProvider);
128
+
129
+ await orchestrator.broadcastMessage(providers, {
130
+ content: 'Test',
131
+ platforms: ['chatkit']
132
+ });
133
+
134
+ const messages = orchestrator.getAllMessages();
135
+ const messageId = messages[0].id;
136
+
137
+ const retrieved = orchestrator.getMessage(messageId);
138
+ expect(retrieved).toBeDefined();
139
+ expect(retrieved?.id).toBe(messageId);
140
+ });
141
+
142
+ it('should filter messages by status', async () => {
143
+ const providers = new Map();
144
+ providers.set('chatkit', mockProvider);
145
+
146
+ await orchestrator.broadcastMessage(providers, {
147
+ content: 'Test',
148
+ platforms: ['chatkit']
149
+ });
150
+
151
+ const sentMessages = orchestrator.getMessagesByStatus(MessageStatus.SENT);
152
+ expect(sentMessages.length).toBeGreaterThan(0);
153
+ });
154
+
155
+ it('should update message status', async () => {
156
+ const providers = new Map();
157
+ providers.set('chatkit', mockProvider);
158
+
159
+ await orchestrator.broadcastMessage(providers, {
160
+ content: 'Test',
161
+ platforms: ['chatkit']
162
+ });
163
+
164
+ const messages = orchestrator.getAllMessages();
165
+ const messageId = messages[0].id;
166
+
167
+ const updated = orchestrator.updateMessageStatus(messageId, MessageStatus.FAILED);
168
+ expect(updated).toBe(true);
169
+
170
+ const message = orchestrator.getMessage(messageId);
171
+ expect(message?.status).toBe(MessageStatus.FAILED);
172
+ });
173
+ });
174
+
175
+ describe('statistics', () => {
176
+ it('should provide message statistics', async () => {
177
+ const providers = new Map();
178
+ providers.set('chatkit', mockProvider);
179
+
180
+ await orchestrator.broadcastMessage(providers, {
181
+ content: 'Test 1',
182
+ platforms: ['chatkit'],
183
+ priority: MessagePriority.HIGH
184
+ });
185
+
186
+ await orchestrator.broadcastMessage(providers, {
187
+ content: 'Test 2',
188
+ platforms: ['chatkit'],
189
+ priority: MessagePriority.NORMAL
190
+ });
191
+
192
+ const stats = orchestrator.getStats();
193
+ expect(stats.total).toBe(2);
194
+ expect(stats.byPriority[MessagePriority.HIGH]).toBe(1);
195
+ expect(stats.byPriority[MessagePriority.NORMAL]).toBe(1);
196
+ });
197
+
198
+ it('should get message count', async () => {
199
+ const providers = new Map();
200
+ providers.set('chatkit', mockProvider);
201
+
202
+ await orchestrator.broadcastMessage(providers, {
203
+ content: 'Test',
204
+ platforms: ['chatkit']
205
+ });
206
+
207
+ expect(orchestrator.getMessageCount()).toBe(1);
208
+ });
209
+
210
+ it('should clear messages', async () => {
211
+ const providers = new Map();
212
+ providers.set('chatkit', mockProvider);
213
+
214
+ await orchestrator.broadcastMessage(providers, {
215
+ content: 'Test',
216
+ platforms: ['chatkit']
217
+ });
218
+
219
+ orchestrator.clearMessages();
220
+ expect(orchestrator.getMessageCount()).toBe(0);
221
+ });
222
+ });
223
+ });