@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,384 +0,0 @@
1
- import { Component } from "@angular/core";
2
- import { CommonModule } from "@angular/common";
3
- import { TestBed } from "@angular/core/testing";
4
- import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
5
- import { CopilotKitAgentContextDirective } from "../copilotkit-agent-context.directive";
6
- import { CopilotKitService } from "../../core/copilotkit.service";
7
- import { provideCopilotKit } from "../../core/copilotkit.providers";
8
-
9
- // Mock CopilotKitCore
10
- vi.mock("@copilotkitnext/core", () => ({
11
- CopilotKitCore: vi.fn().mockImplementation(() => ({
12
- addContext: vi.fn().mockImplementation(() => "context-id-" + Math.random()),
13
- removeContext: vi.fn(),
14
- setRuntimeUrl: vi.fn(),
15
- setHeaders: vi.fn(),
16
- setProperties: vi.fn(),
17
- setAgents: vi.fn(),
18
- subscribe: vi.fn(() => () => {}),
19
- })),
20
- }));
21
-
22
- // Test components
23
- @Component({
24
- template: `
25
- <div
26
- copilotkitAgentContext
27
- [description]="description"
28
- [value]="value"
29
- ></div>
30
- `,
31
- standalone: true,
32
- imports: [CopilotKitAgentContextDirective],
33
- providers: [provideCopilotKit({})],
34
- })
35
- class TestComponentWithInputs {
36
- description = "Test context";
37
- value: any = { data: "initial" };
38
- }
39
-
40
- @Component({
41
- template: ` <div [copilotkitAgentContext]="context"></div> `,
42
- standalone: true,
43
- imports: [CopilotKitAgentContextDirective],
44
- providers: [provideCopilotKit({})],
45
- })
46
- class TestComponentWithContext {
47
- context = {
48
- description: "Full context",
49
- value: { data: "test" },
50
- };
51
- }
52
-
53
- @Component({
54
- template: `
55
- <div
56
- *ngIf="showContext"
57
- copilotkitAgentContext
58
- description="Conditional"
59
- [value]="value"
60
- ></div>
61
- `,
62
- standalone: true,
63
- imports: [CommonModule, CopilotKitAgentContextDirective],
64
- providers: [provideCopilotKit({})],
65
- })
66
- class TestComponentConditional {
67
- showContext = true;
68
- value = { data: "conditional" };
69
- }
70
-
71
- describe("CopilotKitAgentContextDirective", () => {
72
- let service: CopilotKitService;
73
- let addContextSpy: any;
74
- let removeContextSpy: any;
75
-
76
- beforeEach(() => {
77
- TestBed.configureTestingModule({
78
- providers: [provideCopilotKit({})],
79
- });
80
-
81
- service = TestBed.inject(CopilotKitService);
82
- addContextSpy = vi.spyOn(service.copilotkit, "addContext");
83
- removeContextSpy = vi.spyOn(service.copilotkit, "removeContext");
84
- });
85
-
86
- afterEach(() => {
87
- vi.clearAllMocks();
88
- });
89
-
90
- describe("Initialization", () => {
91
- it("should add context on init with separate inputs", () => {
92
- const fixture = TestBed.createComponent(TestComponentWithInputs);
93
- fixture.detectChanges();
94
-
95
- expect(addContextSpy).toHaveBeenCalledWith({
96
- description: "Test context",
97
- value: { data: "initial" },
98
- });
99
- expect(addContextSpy).toHaveBeenCalledTimes(1);
100
- });
101
-
102
- it("should add context on init with context object", () => {
103
- const fixture = TestBed.createComponent(TestComponentWithContext);
104
- fixture.detectChanges();
105
-
106
- expect(addContextSpy).toHaveBeenCalledWith({
107
- description: "Full context",
108
- value: { data: "test" },
109
- });
110
- expect(addContextSpy).toHaveBeenCalledTimes(1);
111
- });
112
-
113
- it("should not add context if inputs are undefined", () => {
114
- @Component({
115
- template: `<div copilotkitAgentContext></div>`,
116
- standalone: true,
117
- imports: [CopilotKitAgentContextDirective],
118
- })
119
- class EmptyComponent {}
120
-
121
- const fixture = TestBed.createComponent(EmptyComponent);
122
- fixture.detectChanges();
123
-
124
- expect(addContextSpy).not.toHaveBeenCalled();
125
- });
126
- });
127
-
128
- describe("Value Updates", () => {
129
- it("should update context when value changes", () => {
130
- const fixture = TestBed.createComponent(TestComponentWithInputs);
131
- fixture.detectChanges();
132
-
133
- // Initial context added
134
- expect(addContextSpy).toHaveBeenCalledTimes(1);
135
- const firstContextId = addContextSpy.mock.results[0].value;
136
-
137
- // Update value
138
- fixture.componentInstance.value = { data: "updated" };
139
- fixture.detectChanges();
140
-
141
- // Should remove old and add new
142
- expect(removeContextSpy).toHaveBeenCalledWith(firstContextId);
143
- expect(addContextSpy).toHaveBeenCalledTimes(2);
144
- expect(addContextSpy).toHaveBeenLastCalledWith({
145
- description: "Test context",
146
- value: { data: "updated" },
147
- });
148
- });
149
-
150
- it("should update context when description changes", () => {
151
- const fixture = TestBed.createComponent(TestComponentWithInputs);
152
- fixture.detectChanges();
153
-
154
- const firstContextId = addContextSpy.mock.results[0].value;
155
-
156
- // Update description
157
- fixture.componentInstance.description = "Updated description";
158
- fixture.detectChanges();
159
-
160
- expect(removeContextSpy).toHaveBeenCalledWith(firstContextId);
161
- expect(addContextSpy).toHaveBeenCalledTimes(2);
162
- expect(addContextSpy).toHaveBeenLastCalledWith({
163
- description: "Updated description",
164
- value: { data: "initial" },
165
- });
166
- });
167
-
168
- it("should update context when context object changes", () => {
169
- const fixture = TestBed.createComponent(TestComponentWithContext);
170
- fixture.detectChanges();
171
-
172
- const firstContextId = addContextSpy.mock.results[0].value;
173
-
174
- // Update entire context
175
- fixture.componentInstance.context = {
176
- description: "New context",
177
- value: { data: "new" },
178
- };
179
- fixture.detectChanges();
180
-
181
- expect(removeContextSpy).toHaveBeenCalledWith(firstContextId);
182
- expect(addContextSpy).toHaveBeenCalledTimes(2);
183
- expect(addContextSpy).toHaveBeenLastCalledWith({
184
- description: "New context",
185
- value: { data: "new" },
186
- });
187
- });
188
-
189
- it("should handle rapid updates correctly", () => {
190
- const fixture = TestBed.createComponent(TestComponentWithInputs);
191
- fixture.detectChanges();
192
-
193
- // Rapid updates
194
- for (let i = 1; i <= 5; i++) {
195
- fixture.componentInstance.value = { data: `update-${i}` };
196
- fixture.detectChanges();
197
- }
198
-
199
- // Should have called addContext 6 times (1 initial + 5 updates)
200
- expect(addContextSpy).toHaveBeenCalledTimes(6);
201
- // Should have called removeContext 5 times (before each update)
202
- expect(removeContextSpy).toHaveBeenCalledTimes(5);
203
-
204
- // Last call should have latest value
205
- expect(addContextSpy).toHaveBeenLastCalledWith({
206
- description: "Test context",
207
- value: { data: "update-5" },
208
- });
209
- });
210
- });
211
-
212
- describe("Cleanup", () => {
213
- it("should remove context on destroy", () => {
214
- const fixture = TestBed.createComponent(TestComponentWithInputs);
215
- fixture.detectChanges();
216
-
217
- const contextId = addContextSpy.mock.results[0].value;
218
-
219
- // Destroy component
220
- fixture.destroy();
221
-
222
- expect(removeContextSpy).toHaveBeenCalledWith(contextId);
223
- });
224
-
225
- it("should handle conditional rendering correctly", () => {
226
- const fixture = TestBed.createComponent(TestComponentConditional);
227
- fixture.detectChanges();
228
-
229
- expect(addContextSpy).toHaveBeenCalledTimes(1);
230
- const contextId = addContextSpy.mock.results[0].value;
231
-
232
- // Hide the element (removes directive)
233
- fixture.componentInstance.showContext = false;
234
- fixture.detectChanges();
235
-
236
- expect(removeContextSpy).toHaveBeenCalledWith(contextId);
237
-
238
- // Show again (creates new directive instance)
239
- fixture.componentInstance.showContext = true;
240
- fixture.detectChanges();
241
-
242
- expect(addContextSpy).toHaveBeenCalledTimes(2);
243
- });
244
-
245
- it("should not throw when removing non-existent context", () => {
246
- @Component({
247
- template: `<div copilotkitAgentContext></div>`,
248
- standalone: true,
249
- imports: [CopilotKitAgentContextDirective],
250
- })
251
- class EmptyComponent {}
252
-
253
- const fixture = TestBed.createComponent(EmptyComponent);
254
- fixture.detectChanges();
255
-
256
- // No context was added, but destroy should not throw
257
- expect(() => fixture.destroy()).not.toThrow();
258
- expect(removeContextSpy).not.toHaveBeenCalled();
259
- });
260
- });
261
-
262
- describe("Complex Scenarios", () => {
263
- it("should handle multiple directives on the same page", () => {
264
- @Component({
265
- template: `
266
- <div
267
- copilotkitAgentContext
268
- description="Context 1"
269
- [value]="value1"
270
- ></div>
271
- <div
272
- copilotkitAgentContext
273
- description="Context 2"
274
- [value]="value2"
275
- ></div>
276
- `,
277
- standalone: true,
278
- imports: [CopilotKitAgentContextDirective],
279
- })
280
- class MultipleContextComponent {
281
- value1 = { id: 1 };
282
- value2 = { id: 2 };
283
- }
284
-
285
- const fixture = TestBed.createComponent(MultipleContextComponent);
286
- fixture.detectChanges();
287
-
288
- expect(addContextSpy).toHaveBeenCalledTimes(2);
289
- expect(addContextSpy).toHaveBeenCalledWith({
290
- description: "Context 1",
291
- value: { id: 1 },
292
- });
293
- expect(addContextSpy).toHaveBeenCalledWith({
294
- description: "Context 2",
295
- value: { id: 2 },
296
- });
297
-
298
- fixture.destroy();
299
-
300
- // Both contexts should be removed
301
- expect(removeContextSpy).toHaveBeenCalledTimes(2);
302
- });
303
-
304
- it("should handle null values", () => {
305
- const fixture = TestBed.createComponent(TestComponentWithInputs);
306
- fixture.componentInstance.value = null;
307
- fixture.detectChanges();
308
-
309
- expect(addContextSpy).toHaveBeenCalledWith({
310
- description: "Test context",
311
- value: null,
312
- });
313
- });
314
-
315
- it("should not add context when value is undefined", () => {
316
- const fixture = TestBed.createComponent(TestComponentWithInputs);
317
- fixture.componentInstance.value = undefined;
318
- fixture.componentInstance.description = "Test";
319
- fixture.detectChanges();
320
-
321
- // Directive shouldn't add context if value is undefined
322
- expect(addContextSpy).not.toHaveBeenCalled();
323
- });
324
-
325
- it("should handle complex nested objects", () => {
326
- const fixture = TestBed.createComponent(TestComponentWithInputs);
327
- const complexValue = {
328
- user: {
329
- id: 123,
330
- preferences: {
331
- theme: "dark",
332
- notifications: ["email", "push"],
333
- settings: {
334
- language: "en",
335
- timezone: "UTC",
336
- },
337
- },
338
- },
339
- metadata: {
340
- timestamp: Date.now(),
341
- version: "1.0.0",
342
- },
343
- };
344
-
345
- fixture.componentInstance.value = complexValue;
346
- fixture.detectChanges();
347
-
348
- expect(addContextSpy).toHaveBeenCalledWith({
349
- description: "Test context",
350
- value: complexValue,
351
- });
352
- });
353
- });
354
-
355
- describe("Priority of Inputs", () => {
356
- it("should prioritize context object over individual inputs", () => {
357
- @Component({
358
- template: `
359
- <div
360
- [copilotkitAgentContext]="context"
361
- [description]="description"
362
- [value]="value"
363
- ></div>
364
- `,
365
- standalone: true,
366
- imports: [CopilotKitAgentContextDirective],
367
- })
368
- class PriorityComponent {
369
- context = { description: "Context object", value: "context-value" };
370
- description = "Individual description";
371
- value = "individual-value";
372
- }
373
-
374
- const fixture = TestBed.createComponent(PriorityComponent);
375
- fixture.detectChanges();
376
-
377
- // Should use context object, not individual inputs
378
- expect(addContextSpy).toHaveBeenCalledWith({
379
- description: "Context object",
380
- value: "context-value",
381
- });
382
- });
383
- });
384
- });
@@ -1,253 +0,0 @@
1
- import { Component } from "@angular/core";
2
- import { TestBed } from "@angular/core/testing";
3
- import { describe, it, expect, beforeEach, vi, afterEach } from "vitest";
4
- import { CopilotKitAgentDirective } from "../copilotkit-agent.directive";
5
- import { CopilotKitService } from "../../core/copilotkit.service";
6
- import { provideCopilotKit } from "../../core/copilotkit.providers";
7
- import { DEFAULT_AGENT_ID } from "@copilotkitnext/shared";
8
-
9
- // Mock agent
10
- const mockAgent = {
11
- id: "test-agent",
12
- state: {},
13
- messages: [],
14
- subscribe: vi.fn((callbacks: any) => {
15
- // Store callbacks for testing
16
- (mockAgent as any)._callbacks = callbacks;
17
- return {
18
- unsubscribe: vi.fn(),
19
- };
20
- }),
21
- _callbacks: null as any,
22
- // Helper to trigger events
23
- _trigger: (event: string, params?: any) => {
24
- if ((mockAgent as any)._callbacks && (mockAgent as any)._callbacks[event]) {
25
- (mockAgent as any)._callbacks[event](params);
26
- }
27
- },
28
- };
29
-
30
- // Mock CopilotKitCore
31
- const mockCopilotKitCore = {
32
- addTool: vi.fn(),
33
- removeTool: vi.fn(),
34
- setRuntimeUrl: vi.fn(),
35
- setHeaders: vi.fn(),
36
- setProperties: vi.fn(),
37
- setAgents: vi.fn(),
38
- getAgent: vi.fn((id: string) =>
39
- id === "test-agent" ? mockAgent : undefined
40
- ),
41
- subscribe: vi.fn(() => vi.fn()), // Returns unsubscribe function directly
42
- };
43
-
44
- vi.mock("@copilotkitnext/core", () => ({
45
- CopilotKitCore: vi.fn().mockImplementation(() => mockCopilotKitCore),
46
- }));
47
-
48
- describe("CopilotKitAgentDirective", () => {
49
- let service: CopilotKitService;
50
-
51
- beforeEach(() => {
52
- TestBed.configureTestingModule({
53
- providers: [provideCopilotKit({})],
54
- });
55
-
56
- service = TestBed.inject(CopilotKitService);
57
- vi.clearAllMocks();
58
- (mockAgent as any)._callbacks = null;
59
- });
60
-
61
- afterEach(() => {
62
- vi.clearAllMocks();
63
- });
64
-
65
- describe("Basic Usage", () => {
66
- it("should create directive and emit agent", () => {
67
- let emittedAgent: any;
68
-
69
- @Component({
70
- template: `
71
- <div
72
- copilotkitAgent
73
- [agentId]="'test-agent'"
74
- (agentChange)="onAgentChange($event)"
75
- ></div>
76
- `,
77
- standalone: true,
78
- imports: [CopilotKitAgentDirective],
79
- })
80
- class TestComponent {
81
- onAgentChange(agent: any) {
82
- emittedAgent = agent;
83
- }
84
- }
85
-
86
- const fixture = TestBed.createComponent(TestComponent);
87
- fixture.detectChanges();
88
-
89
- expect(emittedAgent).toBe(mockAgent);
90
- expect(mockCopilotKitCore.getAgent).toHaveBeenCalledWith("test-agent");
91
- });
92
-
93
- it("should use default agent ID when not provided", () => {
94
- @Component({
95
- template: `<div copilotkitAgent></div>`,
96
- standalone: true,
97
- imports: [CopilotKitAgentDirective],
98
- })
99
- class TestComponent {}
100
-
101
- const fixture = TestBed.createComponent(TestComponent);
102
- fixture.detectChanges();
103
-
104
- expect(mockCopilotKitCore.getAgent).toHaveBeenCalledWith(
105
- DEFAULT_AGENT_ID
106
- );
107
- });
108
-
109
- it("should support directive selector binding", () => {
110
- @Component({
111
- template: `<div [copilotkitAgent]="'test-agent'"></div>`,
112
- standalone: true,
113
- imports: [CopilotKitAgentDirective],
114
- })
115
- class TestComponent {}
116
-
117
- const fixture = TestBed.createComponent(TestComponent);
118
- fixture.detectChanges();
119
-
120
- expect(mockCopilotKitCore.getAgent).toHaveBeenCalledWith("test-agent");
121
- });
122
- });
123
-
124
- describe("Event Emissions", () => {
125
- it("should emit running state changes", () => {
126
- let isRunning = false;
127
-
128
- @Component({
129
- template: `
130
- <div
131
- copilotkitAgent
132
- [agentId]="'test-agent'"
133
- (runningChange)="onRunningChange($event)"
134
- ></div>
135
- `,
136
- standalone: true,
137
- imports: [CopilotKitAgentDirective],
138
- })
139
- class TestComponent {
140
- onRunningChange(running: boolean) {
141
- isRunning = running;
142
- }
143
- }
144
-
145
- const fixture = TestBed.createComponent(TestComponent);
146
- fixture.detectChanges();
147
-
148
- // Trigger run initialized
149
- (mockAgent as any)._trigger("onRunInitialized", { runId: "123" });
150
- expect(isRunning).toBe(true);
151
-
152
- // Trigger run finalized
153
- (mockAgent as any)._trigger("onRunFinalized", { runId: "123" });
154
- expect(isRunning).toBe(false);
155
- });
156
-
157
- it("should emit run failed and set running to false", () => {
158
- let isRunning = true;
159
- let failedEvent: any;
160
-
161
- @Component({
162
- template: `
163
- <div
164
- copilotkitAgent
165
- [agentId]="'test-agent'"
166
- (runningChange)="isRunning = $event"
167
- (runFailed)="onRunFailed($event)"
168
- ></div>
169
- `,
170
- standalone: true,
171
- imports: [CopilotKitAgentDirective],
172
- })
173
- class TestComponent {
174
- isRunning = true;
175
- onRunFailed(event: any) {
176
- failedEvent = event;
177
- }
178
- }
179
-
180
- const fixture = TestBed.createComponent(TestComponent);
181
- fixture.detectChanges();
182
-
183
- // Trigger run failed
184
- const errorData = { error: "Test error" };
185
- (mockAgent as any)._trigger("onRunFailed", errorData);
186
-
187
- expect(fixture.componentInstance.isRunning).toBe(false);
188
- expect(failedEvent).toEqual(errorData);
189
- });
190
-
191
- it("should emit messages and state changes", () => {
192
- let messagesData: any;
193
- let stateData: any;
194
-
195
- @Component({
196
- template: `
197
- <div
198
- copilotkitAgent
199
- [agentId]="'test-agent'"
200
- (messagesChange)="onMessagesChange($event)"
201
- (stateChange)="onStateChange($event)"
202
- ></div>
203
- `,
204
- standalone: true,
205
- imports: [CopilotKitAgentDirective],
206
- })
207
- class TestComponent {
208
- onMessagesChange(data: any) {
209
- messagesData = data;
210
- }
211
- onStateChange(data: any) {
212
- stateData = data;
213
- }
214
- }
215
-
216
- const fixture = TestBed.createComponent(TestComponent);
217
- fixture.detectChanges();
218
-
219
- // Trigger messages change
220
- const messages = { messages: ["msg1", "msg2"] };
221
- (mockAgent as any)._trigger("onMessagesChanged", messages);
222
- expect(messagesData).toEqual(messages);
223
-
224
- // Trigger state change
225
- const state = { state: "updated" };
226
- (mockAgent as any)._trigger("onStateChanged", state);
227
- expect(stateData).toEqual(state);
228
- });
229
- });
230
-
231
- describe("Cleanup", () => {
232
- it("should unsubscribe on destroy", () => {
233
- const unsubscribeSpy = vi.fn();
234
- mockAgent.subscribe = vi.fn(() => ({
235
- unsubscribe: unsubscribeSpy,
236
- }));
237
-
238
- @Component({
239
- template: `<div copilotkitAgent [agentId]="'test-agent'"></div>`,
240
- standalone: true,
241
- imports: [CopilotKitAgentDirective],
242
- })
243
- class TestComponent {}
244
-
245
- const fixture = TestBed.createComponent(TestComponent);
246
- fixture.detectChanges();
247
-
248
- fixture.destroy();
249
-
250
- expect(unsubscribeSpy).toHaveBeenCalled();
251
- });
252
- });
253
- });