@copilotkitnext/angular 0.0.1 → 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 (171) hide show
  1. package/README.md +248 -0
  2. package/dist/README.md +248 -0
  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/dist/styles.css +0 -27
  72. package/package.json +23 -20
  73. package/vitest.config.mts +32 -21
  74. package/.turbo/turbo-build.log +0 -39
  75. package/.turbo/turbo-check-types.log +0 -0
  76. package/.turbo/turbo-test.log +0 -71
  77. package/README-agent-context.md +0 -310
  78. package/ng-package.json +0 -19
  79. package/slots.md +0 -331
  80. package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
  81. package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
  82. package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
  83. package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
  84. package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
  85. package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
  86. package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
  87. package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
  88. package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
  89. package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
  90. package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
  91. package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
  92. package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
  93. package/src/components/chat/copilot-chat-input.component.ts +0 -512
  94. package/src/components/chat/copilot-chat-input.types.ts +0 -148
  95. package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
  96. package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
  97. package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
  98. package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
  99. package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
  100. package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
  101. package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
  102. package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
  103. package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
  104. package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
  105. package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
  106. package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
  107. package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
  108. package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
  109. package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
  110. package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
  111. package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
  112. package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
  113. package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
  114. package/src/components/chat/copilot-chat-view.component.ts +0 -420
  115. package/src/components/chat/copilot-chat-view.types.ts +0 -52
  116. package/src/components/chat/copilot-chat.component.ts +0 -232
  117. package/src/components/copilotkit-tool-render.component.ts +0 -169
  118. package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
  119. package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
  120. package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
  121. package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
  122. package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
  123. package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
  124. package/src/core/copilotkit.providers.ts +0 -59
  125. package/src/core/copilotkit.service.ts +0 -542
  126. package/src/core/copilotkit.types.ts +0 -132
  127. package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
  128. package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
  129. package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
  130. package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
  131. package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
  132. package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
  133. package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
  134. package/src/directives/copilotkit-agent-context.directive.ts +0 -138
  135. package/src/directives/copilotkit-agent.directive.ts +0 -225
  136. package/src/directives/copilotkit-chat-config.directive.ts +0 -241
  137. package/src/directives/copilotkit-config.directive.ts +0 -81
  138. package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
  139. package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
  140. package/src/directives/stick-to-bottom.directive.ts +0 -204
  141. package/src/index.ts +0 -105
  142. package/src/lib/directives/tooltip.directive.ts +0 -292
  143. package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
  144. package/src/lib/slots/copilot-slot.component.ts +0 -135
  145. package/src/lib/slots/index.ts +0 -3
  146. package/src/lib/slots/slot.types.ts +0 -64
  147. package/src/lib/slots/slot.utils.ts +0 -289
  148. package/src/lib/utils.ts +0 -10
  149. package/src/public-api.ts +0 -1
  150. package/src/services/resize-observer.service.ts +0 -181
  151. package/src/services/scroll-position.service.ts +0 -169
  152. package/src/styles/globals.css +0 -266
  153. package/src/styles/index.css +0 -3
  154. package/src/test-setup.ts +0 -15
  155. package/src/testing/index.ts +0 -3
  156. package/src/testing/testing.utils.ts +0 -248
  157. package/src/types/frontend-tool.ts +0 -44
  158. package/src/types/human-in-the-loop.ts +0 -52
  159. package/src/utils/__tests__/agent.utils.spec.ts +0 -234
  160. package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
  161. package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
  162. package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
  163. package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
  164. package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
  165. package/src/utils/agent-context.utils.ts +0 -133
  166. package/src/utils/agent.utils.ts +0 -239
  167. package/src/utils/chat-config.utils.ts +0 -221
  168. package/src/utils/copilotkit.utils.ts +0 -20
  169. package/src/utils/frontend-tool.utils.ts +0 -266
  170. package/src/utils/human-in-the-loop.utils.ts +0 -359
  171. 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
- }