@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,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
- });