@copilotkitnext/angular 0.0.2 → 0.0.4

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 (168) hide show
  1. package/README.md +3 -3
  2. package/dist/README.md +3 -3
  3. package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
  4. package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
  5. package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
  6. package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
  7. package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
  8. package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
  9. package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
  10. package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
  11. package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
  12. package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
  13. package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
  14. package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
  15. package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
  16. package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
  17. package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
  18. package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
  19. package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
  20. package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
  21. package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
  22. package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
  23. package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
  24. package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
  25. package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
  26. package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
  27. package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
  28. package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
  29. package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
  30. package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
  31. package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
  32. package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
  33. package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
  34. package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
  35. package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
  36. package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
  37. package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
  38. package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
  39. package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
  40. package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
  41. package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
  42. package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
  43. package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
  44. package/dist/esm2022/core/copilotkit.service.mjs +430 -0
  45. package/dist/esm2022/core/copilotkit.types.mjs +12 -0
  46. package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
  47. package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
  48. package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
  49. package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
  50. package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +130 -0
  51. package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +266 -0
  52. package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
  53. package/dist/esm2022/index.mjs +70 -0
  54. package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
  55. package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
  56. package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
  57. package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
  58. package/dist/esm2022/lib/utils.mjs +10 -0
  59. package/dist/esm2022/services/resize-observer.service.mjs +152 -0
  60. package/dist/esm2022/services/scroll-position.service.mjs +124 -0
  61. package/dist/esm2022/types/frontend-tool.mjs +2 -0
  62. package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
  63. package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
  64. package/dist/esm2022/utils/agent.utils.mjs +204 -0
  65. package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
  66. package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
  67. package/dist/esm2022/utils/frontend-tool.utils.mjs +228 -0
  68. package/dist/esm2022/utils/human-in-the-loop.utils.mjs +296 -0
  69. package/dist/fesm2022/copilotkitnext-angular.mjs +163 -164
  70. package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
  71. package/package.json +21 -18
  72. package/vitest.config.mts +32 -21
  73. package/.turbo/turbo-build.log +0 -38
  74. package/.turbo/turbo-check-types.log +0 -0
  75. package/.turbo/turbo-test.log +0 -71
  76. package/ng-package.json +0 -19
  77. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  78. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  79. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  80. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  81. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  82. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  83. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  84. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  85. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  86. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  87. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  88. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  89. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  90. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  91. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  92. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  93. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  94. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  95. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  96. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  97. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  98. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  99. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  100. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  101. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  102. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  103. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  104. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  105. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  106. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  107. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  108. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  109. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  110. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  111. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  112. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  113. package/src/components/chat/copilot-chat.component.ts +0 -232
  114. package/src/components/copilotkit-tool-render.component.ts +0 -169
  115. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  116. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  117. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  118. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  119. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  120. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  121. package/src/core/copilotkit.providers.ts +0 -59
  122. package/src/core/copilotkit.service.ts +0 -542
  123. package/src/core/copilotkit.types.ts +0 -132
  124. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  125. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  126. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  127. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  128. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  129. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  130. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  131. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  132. package/src/directives/copilotkit-agent.directive.ts +0 -225
  133. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  134. package/src/directives/copilotkit-config.directive.ts +0 -81
  135. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  136. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  137. package/src/directives/stick-to-bottom.directive.ts +0 -204
  138. package/src/index.ts +0 -105
  139. package/src/lib/directives/tooltip.directive.ts +0 -292
  140. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  141. package/src/lib/slots/copilot-slot.component.ts +0 -135
  142. package/src/lib/slots/index.ts +0 -3
  143. package/src/lib/slots/slot.types.ts +0 -64
  144. package/src/lib/slots/slot.utils.ts +0 -289
  145. package/src/lib/utils.ts +0 -10
  146. package/src/public-api.ts +0 -1
  147. package/src/services/resize-observer.service.ts +0 -181
  148. package/src/services/scroll-position.service.ts +0 -169
  149. package/src/styles/globals.css +0 -266
  150. package/src/styles/index.css +0 -3
  151. package/src/test-setup.ts +0 -15
  152. package/src/testing/index.ts +0 -3
  153. package/src/testing/testing.utils.ts +0 -248
  154. package/src/types/frontend-tool.ts +0 -44
  155. package/src/types/human-in-the-loop.ts +0 -52
  156. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  157. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  158. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  159. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  160. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  161. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  162. package/src/utils/agent-context.utils.ts +0 -133
  163. package/src/utils/agent.utils.ts +0 -239
  164. package/src/utils/chat-config.utils.ts +0 -221
  165. package/src/utils/copilotkit.utils.ts +0 -20
  166. package/src/utils/frontend-tool.utils.ts +0 -266
  167. package/src/utils/human-in-the-loop.utils.ts +0 -359
  168. package/tsconfig.spec.json +0 -12
@@ -1,316 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { describe, it, expect, beforeEach, vi } from 'vitest';
3
- import { CopilotKitService } from '../copilotkit.service';
4
- import { Component } from '@angular/core';
5
- import { provideCopilotKit } from '../copilotkit.providers';
6
- import { AngularFrontendTool } from '../../types/frontend-tool';
7
- import { AngularHumanInTheLoop } from '../../types/human-in-the-loop';
8
- import { z } from 'zod';
9
-
10
- describe('CopilotKitService - Wildcard Tool', () => {
11
- beforeEach(() => {
12
- TestBed.resetTestingModule();
13
- });
14
-
15
- describe('Wildcard Frontend Tool', () => {
16
- it('should register wildcard frontend tool', () => {
17
- const wildcardHandler = vi.fn(async ({ toolName, args }) =>
18
- `Handled ${toolName}`
19
- );
20
-
21
- const wildcardTool: AngularFrontendTool = {
22
- name: '*',
23
- description: 'Fallback for undefined tools',
24
- handler: wildcardHandler,
25
- };
26
-
27
- TestBed.configureTestingModule({
28
- providers: [
29
- provideCopilotKit({
30
- frontendTools: [wildcardTool],
31
- }),
32
- ],
33
- });
34
- const service = TestBed.inject(CopilotKitService);
35
-
36
- expect(service.copilotkit.tools['*']).toBeDefined();
37
- expect(service.copilotkit.tools['*'].name).toBe('*');
38
- expect(service.copilotkit.tools['*'].handler).toBe(wildcardHandler);
39
- });
40
-
41
- it('should register wildcard alongside specific tools', () => {
42
- const specificHandler = vi.fn();
43
- const wildcardHandler = vi.fn();
44
-
45
- const specificTool: AngularFrontendTool = {
46
- name: 'specific',
47
- handler: specificHandler,
48
- };
49
-
50
- const wildcardTool: AngularFrontendTool = {
51
- name: '*',
52
- handler: wildcardHandler,
53
- };
54
-
55
- TestBed.configureTestingModule({
56
- providers: [
57
- provideCopilotKit({
58
- frontendTools: [specificTool, wildcardTool],
59
- }),
60
- ],
61
- });
62
- const service = TestBed.inject(CopilotKitService);
63
-
64
- expect(service.copilotkit.tools['specific']).toBeDefined();
65
- expect(service.copilotkit.tools['*']).toBeDefined();
66
- });
67
-
68
- it('should register wildcard with render component', () => {
69
- @Component({
70
- selector: 'app-wildcard-render',
71
- template: '<div>Unknown tool: {{ args.toolName }}</div>',
72
- standalone: true,
73
- })
74
- class WildcardRenderComponent {
75
- args: any;
76
- }
77
-
78
- const wildcardTool: AngularFrontendTool = {
79
- name: '*',
80
- description: 'Fallback with render',
81
- parameters: z.object({
82
- toolName: z.string(),
83
- args: z.unknown(),
84
- }),
85
- render: WildcardRenderComponent,
86
- };
87
-
88
- TestBed.configureTestingModule({
89
- providers: [
90
- provideCopilotKit({
91
- frontendTools: [wildcardTool],
92
- }),
93
- ],
94
- });
95
- const service = TestBed.inject(CopilotKitService);
96
-
97
- const renderToolCalls = service.renderToolCalls();
98
- const wildcardRender = renderToolCalls.find(r => r.name === '*');
99
- expect(wildcardRender).toBeDefined();
100
- expect(wildcardRender?.render).toBe(WildcardRenderComponent);
101
- });
102
-
103
- it('should support wildcard with agentId', () => {
104
- const wildcardHandler = vi.fn();
105
- const wildcardTool: AngularFrontendTool = {
106
- name: '*',
107
- handler: wildcardHandler,
108
- agentId: 'specificAgent',
109
- };
110
-
111
- TestBed.configureTestingModule({
112
- providers: [
113
- provideCopilotKit({
114
- frontendTools: [wildcardTool],
115
- }),
116
- ],
117
- });
118
- const service = TestBed.inject(CopilotKitService);
119
-
120
- expect(service.copilotkit.tools['*'].agentId).toBe('specificAgent');
121
- });
122
- });
123
-
124
- describe('Wildcard Human-in-the-Loop', () => {
125
- it('should register wildcard human-in-the-loop tool', () => {
126
- @Component({
127
- selector: 'app-wildcard-interaction',
128
- template: '<div>Unknown interaction: {{ args.toolName }}</div>',
129
- standalone: true,
130
- })
131
- class WildcardInteractionComponent {
132
- args: any;
133
- }
134
-
135
- const wildcardHitl: AngularHumanInTheLoop = {
136
- name: '*',
137
- description: 'Fallback interaction',
138
- parameters: z.object({
139
- toolName: z.string(),
140
- args: z.unknown(),
141
- }),
142
- render: WildcardInteractionComponent,
143
- };
144
-
145
- TestBed.configureTestingModule({
146
- providers: [
147
- provideCopilotKit({
148
- humanInTheLoop: [wildcardHitl],
149
- }),
150
- ],
151
- });
152
- const service = TestBed.inject(CopilotKitService);
153
-
154
- expect(service.copilotkit.tools['*']).toBeDefined();
155
- const renderToolCalls = service.renderToolCalls();
156
- const wildcardRender = renderToolCalls.find(r => r.name === '*');
157
- expect(wildcardRender).toBeDefined();
158
- expect(wildcardRender?.render).toBe(WildcardInteractionComponent);
159
- });
160
-
161
- it('should support wildcard human-in-the-loop with agentId', () => {
162
- @Component({
163
- selector: 'app-wildcard',
164
- template: '<div>Wildcard</div>',
165
- standalone: true,
166
- })
167
- class WildcardComponent {}
168
-
169
- const wildcardHitl: AngularHumanInTheLoop = {
170
- name: '*',
171
- parameters: z.object({
172
- toolName: z.string(),
173
- args: z.unknown(),
174
- }),
175
- render: WildcardComponent,
176
- agentId: 'agent1',
177
- };
178
-
179
- TestBed.configureTestingModule({
180
- providers: [
181
- provideCopilotKit({
182
- humanInTheLoop: [wildcardHitl],
183
- }),
184
- ],
185
- });
186
- const service = TestBed.inject(CopilotKitService);
187
-
188
- expect(service.copilotkit.tools['*'].agentId).toBe('agent1');
189
- const renderToolCalls = service.renderToolCalls();
190
- const wildcardRender = renderToolCalls.find(r => r.name === '*');
191
- expect(wildcardRender?.agentId).toBe('agent1');
192
- });
193
- });
194
-
195
- describe('Wildcard Render Tool Calls', () => {
196
- it('should register wildcard in renderToolCalls', () => {
197
- @Component({
198
- selector: 'app-wildcard-render',
199
- template: '<div>Fallback render</div>',
200
- standalone: true,
201
- })
202
- class WildcardRenderComponent {}
203
-
204
- const renderToolCalls = [{
205
- name: '*',
206
- args: z.object({
207
- toolName: z.string(),
208
- args: z.unknown(),
209
- }),
210
- render: WildcardRenderComponent,
211
- }];
212
-
213
- TestBed.configureTestingModule({
214
- providers: [
215
- provideCopilotKit({
216
- renderToolCalls,
217
- }),
218
- ],
219
- });
220
- const service = TestBed.inject(CopilotKitService);
221
-
222
- const currentRenderToolCalls = service.renderToolCalls();
223
- const wildcardRender = currentRenderToolCalls.find(r => r.name === '*');
224
- expect(wildcardRender).toBeDefined();
225
- expect(wildcardRender?.render).toBe(WildcardRenderComponent);
226
- });
227
-
228
- it('should support wildcard render with agentId', () => {
229
- @Component({
230
- selector: 'app-agent-wildcard',
231
- template: '<div>Agent wildcard</div>',
232
- standalone: true,
233
- })
234
- class AgentWildcardComponent {}
235
-
236
- const renderToolCalls = [{
237
- name: '*',
238
- args: z.object({
239
- toolName: z.string(),
240
- args: z.unknown(),
241
- }),
242
- render: AgentWildcardComponent,
243
- agentId: 'agent1',
244
- }];
245
-
246
- TestBed.configureTestingModule({
247
- providers: [
248
- provideCopilotKit({
249
- renderToolCalls,
250
- }),
251
- ],
252
- });
253
- const service = TestBed.inject(CopilotKitService);
254
-
255
- const currentRenderToolCalls = service.renderToolCalls();
256
- const wildcardRender = currentRenderToolCalls.find(r => r.name === '*');
257
- expect(wildcardRender?.agentId).toBe('agent1');
258
- });
259
- });
260
-
261
- describe('Combined wildcard and specific tools', () => {
262
- it('should handle both wildcard and specific tools together', () => {
263
- @Component({
264
- selector: 'app-specific',
265
- template: '<div>Specific</div>',
266
- standalone: true,
267
- })
268
- class SpecificRenderComponent {}
269
-
270
- @Component({
271
- selector: 'app-wildcard',
272
- template: '<div>Wildcard</div>',
273
- standalone: true,
274
- })
275
- class WildcardRenderComponent {}
276
-
277
- const frontendTools: AngularFrontendTool[] = [
278
- {
279
- name: 'specificTool',
280
- handler: vi.fn(),
281
- parameters: z.object({ value: z.string() }),
282
- render: SpecificRenderComponent,
283
- },
284
- {
285
- name: '*',
286
- handler: vi.fn(),
287
- parameters: z.object({
288
- toolName: z.string(),
289
- args: z.unknown(),
290
- }),
291
- render: WildcardRenderComponent,
292
- },
293
- ];
294
-
295
- TestBed.configureTestingModule({
296
- providers: [
297
- provideCopilotKit({
298
- frontendTools,
299
- }),
300
- ],
301
- });
302
- const service = TestBed.inject(CopilotKitService);
303
-
304
- // Both tools should be registered
305
- expect(service.copilotkit.tools['specificTool']).toBeDefined();
306
- expect(service.copilotkit.tools['*']).toBeDefined();
307
-
308
- // Both renders should be registered
309
- const renderToolCalls = service.renderToolCalls();
310
- const specificRender = renderToolCalls.find(r => r.name === 'specificTool');
311
- const wildcardRender = renderToolCalls.find(r => r.name === '*');
312
- expect(specificRender).toBeDefined();
313
- expect(wildcardRender).toBeDefined();
314
- });
315
- });
316
- });
@@ -1,287 +0,0 @@
1
- import { TestBed } from '@angular/core/testing';
2
- import { describe, it, expect, beforeEach, vi } from 'vitest';
3
- import { CopilotChatConfigurationService } from '../chat-configuration.service';
4
- import { provideCopilotChatConfiguration } from '../chat-configuration.providers';
5
- import {
6
- COPILOT_CHAT_DEFAULT_LABELS,
7
- COPILOT_CHAT_INITIAL_CONFIG
8
- } from '../chat-configuration.types';
9
- import { effect } from '@angular/core';
10
-
11
- describe('CopilotChatConfigurationService', () => {
12
- describe('Default Configuration', () => {
13
- let service: CopilotChatConfigurationService;
14
-
15
- beforeEach(() => {
16
- TestBed.configureTestingModule({
17
- providers: [CopilotChatConfigurationService]
18
- });
19
-
20
- service = TestBed.inject(CopilotChatConfigurationService);
21
- });
22
-
23
- it('should create service with default labels', () => {
24
- expect(service).toBeDefined();
25
- expect(service.labels()).toEqual(COPILOT_CHAT_DEFAULT_LABELS);
26
- });
27
-
28
- it('should have undefined input value by default', () => {
29
- expect(service.inputValue()).toBeUndefined();
30
- });
31
-
32
- it('should have no handlers by default', () => {
33
- expect(service.getSubmitHandler()).toBeUndefined();
34
- expect(service.getChangeHandler()).toBeUndefined();
35
- });
36
- });
37
-
38
- describe('With Initial Configuration', () => {
39
- let service: CopilotChatConfigurationService;
40
- const customLabels = {
41
- chatInputPlaceholder: 'Custom placeholder'
42
- };
43
- const submitHandler = vi.fn();
44
- const changeHandler = vi.fn();
45
-
46
- beforeEach(() => {
47
- TestBed.configureTestingModule({
48
- providers: provideCopilotChatConfiguration({
49
- labels: customLabels,
50
- inputValue: 'initial value',
51
- onSubmitInput: submitHandler,
52
- onChangeInput: changeHandler
53
- })
54
- });
55
-
56
- service = TestBed.inject(CopilotChatConfigurationService);
57
- });
58
-
59
- it('should merge custom labels with defaults', () => {
60
- const labels = service.labels();
61
- expect(labels.chatInputPlaceholder).toBe('Custom placeholder');
62
- expect(labels.chatInputToolbarAddButtonLabel).toBe(COPILOT_CHAT_DEFAULT_LABELS.chatInputToolbarAddButtonLabel);
63
- });
64
-
65
- it('should set initial input value', () => {
66
- expect(service.inputValue()).toBe('initial value');
67
- });
68
-
69
- it('should set initial handlers', () => {
70
- expect(service.getSubmitHandler()).toBe(submitHandler);
71
- expect(service.getChangeHandler()).toBe(changeHandler);
72
- });
73
- });
74
-
75
- describe('Label Management', () => {
76
- let service: CopilotChatConfigurationService;
77
-
78
- beforeEach(() => {
79
- TestBed.configureTestingModule({
80
- providers: [CopilotChatConfigurationService]
81
- });
82
-
83
- service = TestBed.inject(CopilotChatConfigurationService);
84
- });
85
-
86
- it('should update labels partially', () => {
87
- service.setLabels({
88
- chatInputPlaceholder: 'New placeholder',
89
- userMessageToolbarEditMessageLabel: 'Modify'
90
- });
91
-
92
- const labels = service.labels();
93
- expect(labels.chatInputPlaceholder).toBe('New placeholder');
94
- expect(labels.userMessageToolbarEditMessageLabel).toBe('Modify');
95
- expect(labels.chatInputToolbarAddButtonLabel).toBe(COPILOT_CHAT_DEFAULT_LABELS.chatInputToolbarAddButtonLabel);
96
- });
97
-
98
- it('should notify subscribers when labels change', () => {
99
- // Signals update synchronously, no need for effect
100
- service.setLabels({ chatInputPlaceholder: 'Updated' });
101
-
102
- const labelsValue = service.labels();
103
- expect(labelsValue.chatInputPlaceholder).toBe('Updated');
104
- });
105
- });
106
-
107
- describe('Input Value Management', () => {
108
- let service: CopilotChatConfigurationService;
109
- const changeHandler = vi.fn();
110
-
111
- beforeEach(() => {
112
- TestBed.configureTestingModule({
113
- providers: provideCopilotChatConfiguration({
114
- onChangeInput: changeHandler
115
- })
116
- });
117
-
118
- service = TestBed.inject(CopilotChatConfigurationService);
119
- vi.clearAllMocks();
120
- });
121
-
122
- it('should update input value', () => {
123
- service.setInputValue('test value');
124
- expect(service.inputValue()).toBe('test value');
125
- });
126
-
127
- it('should trigger change handler when setting value', () => {
128
- service.setInputValue('new value');
129
- expect(changeHandler).toHaveBeenCalledWith('new value');
130
- });
131
-
132
- it('should not trigger change handler for undefined', () => {
133
- service.setInputValue(undefined);
134
- expect(changeHandler).not.toHaveBeenCalled();
135
- });
136
- });
137
-
138
- describe('Submit and Change Handlers', () => {
139
- let service: CopilotChatConfigurationService;
140
-
141
- beforeEach(() => {
142
- TestBed.configureTestingModule({
143
- providers: [CopilotChatConfigurationService]
144
- });
145
-
146
- service = TestBed.inject(CopilotChatConfigurationService);
147
- });
148
-
149
- it('should set and call submit handler', () => {
150
- const submitHandler = vi.fn();
151
- service.setSubmitHandler(submitHandler);
152
-
153
- service.submitInput('test message');
154
-
155
- expect(submitHandler).toHaveBeenCalledWith('test message');
156
- });
157
-
158
- it('should set and call change handler', () => {
159
- const changeHandler = vi.fn();
160
- service.setChangeHandler(changeHandler);
161
-
162
- service.changeInput('typing...');
163
-
164
- expect(changeHandler).toHaveBeenCalledWith('typing...');
165
- });
166
-
167
- it('should handle missing handlers gracefully', () => {
168
- expect(() => service.submitInput('test')).not.toThrow();
169
- expect(() => service.changeInput('test')).not.toThrow();
170
- });
171
-
172
- it('should replace handlers', () => {
173
- const handler1 = vi.fn();
174
- const handler2 = vi.fn();
175
-
176
- service.setSubmitHandler(handler1);
177
- service.submitInput('first');
178
- expect(handler1).toHaveBeenCalledWith('first');
179
-
180
- service.setSubmitHandler(handler2);
181
- service.submitInput('second');
182
- expect(handler2).toHaveBeenCalledWith('second');
183
- expect(handler1).toHaveBeenCalledTimes(1);
184
- });
185
- });
186
-
187
- describe('Update Configuration', () => {
188
- let service: CopilotChatConfigurationService;
189
-
190
- beforeEach(() => {
191
- TestBed.configureTestingModule({
192
- providers: [CopilotChatConfigurationService]
193
- });
194
-
195
- service = TestBed.inject(CopilotChatConfigurationService);
196
- });
197
-
198
- it('should update entire configuration at once', () => {
199
- const submitHandler = vi.fn();
200
- const changeHandler = vi.fn();
201
-
202
- service.updateConfiguration({
203
- labels: { chatInputPlaceholder: 'Updated' },
204
- inputValue: 'new value',
205
- onSubmitInput: submitHandler,
206
- onChangeInput: changeHandler
207
- });
208
-
209
- expect(service.labels().chatInputPlaceholder).toBe('Updated');
210
- expect(service.inputValue()).toBe('new value');
211
- expect(service.getSubmitHandler()).toBe(submitHandler);
212
- expect(service.getChangeHandler()).toBe(changeHandler);
213
- });
214
-
215
- it('should handle partial updates', () => {
216
- service.setInputValue('initial');
217
-
218
- service.updateConfiguration({
219
- labels: { chatInputPlaceholder: 'New' }
220
- });
221
-
222
- expect(service.labels().chatInputPlaceholder).toBe('New');
223
- expect(service.inputValue()).toBe('initial');
224
- });
225
- });
226
-
227
- describe('Reset', () => {
228
- let service: CopilotChatConfigurationService;
229
-
230
- beforeEach(() => {
231
- TestBed.configureTestingModule({
232
- providers: provideCopilotChatConfiguration({
233
- labels: { chatInputPlaceholder: 'Custom' },
234
- inputValue: 'test',
235
- onSubmitInput: vi.fn(),
236
- onChangeInput: vi.fn()
237
- })
238
- });
239
-
240
- service = TestBed.inject(CopilotChatConfigurationService);
241
- });
242
-
243
- it('should reset to default configuration', () => {
244
- service.reset();
245
-
246
- expect(service.labels()).toEqual(COPILOT_CHAT_DEFAULT_LABELS);
247
- expect(service.inputValue()).toBeUndefined();
248
- expect(service.getSubmitHandler()).toBeUndefined();
249
- expect(service.getChangeHandler()).toBeUndefined();
250
- });
251
- });
252
-
253
- describe('Multiple Service Instances', () => {
254
- it('should support independent service instances', () => {
255
- // First service with one configuration
256
- const providers1 = provideCopilotChatConfiguration({
257
- labels: { chatInputPlaceholder: 'Service 1' }
258
- });
259
-
260
- // Second service with different configuration
261
- const providers2 = provideCopilotChatConfiguration({
262
- labels: { chatInputPlaceholder: 'Service 2' }
263
- });
264
-
265
- // Create two independent injectors
266
- const injector1 = TestBed.configureTestingModule({
267
- providers: providers1
268
- });
269
-
270
- const service1 = TestBed.inject(CopilotChatConfigurationService);
271
-
272
- // Reset TestBed for second configuration
273
- TestBed.resetTestingModule();
274
-
275
- const injector2 = TestBed.configureTestingModule({
276
- providers: providers2
277
- });
278
-
279
- const service2 = TestBed.inject(CopilotChatConfigurationService);
280
-
281
- // Services should have different configurations
282
- expect(service1).not.toBe(service2);
283
- // Note: Due to TestBed reset, we can't compare values directly
284
- // but in real usage, they would be independent
285
- });
286
- });
287
- });
@@ -1,71 +0,0 @@
1
- import { Provider } from '@angular/core';
2
- import { CopilotChatConfigurationService } from './chat-configuration.service';
3
- import {
4
- CopilotChatConfiguration,
5
- COPILOT_CHAT_INITIAL_CONFIG
6
- } from './chat-configuration.types';
7
-
8
- /**
9
- * Provides CopilotKit chat configuration at a specific component level.
10
- * This allows for scoped configuration where different parts of the app
11
- * can have different chat configurations.
12
- *
13
- * @param config - Optional initial configuration
14
- * @returns Array of providers
15
- *
16
- * @example
17
- * ```typescript
18
- * // Global configuration in app.config.ts
19
- * export const appConfig: ApplicationConfig = {
20
- * providers: [
21
- * provideCopilotChatConfiguration({
22
- * labels: {
23
- * chatInputPlaceholder: "How can I help you today?"
24
- * }
25
- * })
26
- * ]
27
- * };
28
- *
29
- * // Component-scoped configuration
30
- * @Component({
31
- * selector: 'customer-support-chat',
32
- * providers: [
33
- * provideCopilotChatConfiguration({
34
- * labels: {
35
- * chatInputPlaceholder: "Describe your issue..."
36
- * },
37
- * onSubmitInput: (value) => console.log('Support message:', value)
38
- * })
39
- * ],
40
- * template: `...`
41
- * })
42
- * export class CustomerSupportChatComponent {}
43
- *
44
- * // Multiple independent chats
45
- * @Component({
46
- * selector: 'sales-chat',
47
- * providers: [
48
- * provideCopilotChatConfiguration({
49
- * labels: {
50
- * chatInputPlaceholder: "Ask about our products..."
51
- * }
52
- * })
53
- * ],
54
- * template: `...`
55
- * })
56
- * export class SalesChatComponent {}
57
- * ```
58
- */
59
- export function provideCopilotChatConfiguration(
60
- config?: CopilotChatConfiguration
61
- ): Provider[] {
62
- return [
63
- // Provide the service
64
- CopilotChatConfigurationService,
65
- // Provide the initial configuration
66
- {
67
- provide: COPILOT_CHAT_INITIAL_CONFIG,
68
- useValue: config || {}
69
- }
70
- ];
71
- }