@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.
- package/README.md +248 -0
- package/dist/README.md +248 -0
- package/dist/components/chat/copilot-chat-assistant-message.component.d.ts +10 -10
- package/dist/components/chat/copilot-chat-message-view.component.d.ts +42 -42
- package/dist/components/chat/copilot-chat-view.component.d.ts +14 -14
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-buttons.component.mjs +384 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-renderer.component.mjs +286 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message-toolbar.component.mjs +27 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message.component.mjs +433 -0
- package/dist/esm2022/components/chat/copilot-chat-assistant-message.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-audio-recorder.component.mjs +202 -0
- package/dist/esm2022/components/chat/copilot-chat-buttons.component.mjs +321 -0
- package/dist/esm2022/components/chat/copilot-chat-input-defaults.mjs +38 -0
- package/dist/esm2022/components/chat/copilot-chat-input.component.mjs +666 -0
- package/dist/esm2022/components/chat/copilot-chat-input.types.mjs +10 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view-cursor.component.mjs +45 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view.component.mjs +296 -0
- package/dist/esm2022/components/chat/copilot-chat-message-view.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-textarea.component.mjs +188 -0
- package/dist/esm2022/components/chat/copilot-chat-tool-calls-view.component.mjs +216 -0
- package/dist/esm2022/components/chat/copilot-chat-toolbar.component.mjs +25 -0
- package/dist/esm2022/components/chat/copilot-chat-tools-menu.component.mjs +199 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-branch-navigation.component.mjs +137 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-buttons.component.mjs +207 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-renderer.component.mjs +35 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message-toolbar.component.mjs +34 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message.component.mjs +341 -0
- package/dist/esm2022/components/chat/copilot-chat-user-message.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat-view-disclaimer.component.mjs +52 -0
- package/dist/esm2022/components/chat/copilot-chat-view-feather.component.mjs +55 -0
- package/dist/esm2022/components/chat/copilot-chat-view-handlers.service.mjs +19 -0
- package/dist/esm2022/components/chat/copilot-chat-view-input-container.component.mjs +110 -0
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-to-bottom-button.component.mjs +93 -0
- package/dist/esm2022/components/chat/copilot-chat-view-scroll-view.component.mjs +443 -0
- package/dist/esm2022/components/chat/copilot-chat-view.component.mjs +479 -0
- package/dist/esm2022/components/chat/copilot-chat-view.types.mjs +2 -0
- package/dist/esm2022/components/chat/copilot-chat.component.mjs +214 -0
- package/dist/esm2022/components/copilotkit-tool-render.component.mjs +153 -0
- package/dist/esm2022/copilotkitnext-angular.mjs +5 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.providers.mjs +65 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.service.mjs +145 -0
- package/dist/esm2022/core/chat-configuration/chat-configuration.types.mjs +26 -0
- package/dist/esm2022/core/copilotkit.providers.mjs +34 -0
- package/dist/esm2022/core/copilotkit.service.mjs +430 -0
- package/dist/esm2022/core/copilotkit.types.mjs +12 -0
- package/dist/esm2022/directives/copilotkit-agent-context.directive.mjs +130 -0
- package/dist/esm2022/directives/copilotkit-agent.directive.mjs +217 -0
- package/dist/esm2022/directives/copilotkit-chat-config.directive.mjs +218 -0
- package/dist/esm2022/directives/copilotkit-config.directive.mjs +94 -0
- package/dist/esm2022/directives/copilotkit-frontend-tool.directive.mjs +130 -0
- package/dist/esm2022/directives/copilotkit-human-in-the-loop.directive.mjs +266 -0
- package/dist/esm2022/directives/stick-to-bottom.directive.mjs +181 -0
- package/dist/esm2022/index.mjs +70 -0
- package/dist/esm2022/lib/directives/tooltip.directive.mjs +211 -0
- package/dist/esm2022/lib/slots/copilot-slot.component.mjs +144 -0
- package/dist/esm2022/lib/slots/slot.types.mjs +6 -0
- package/dist/esm2022/lib/slots/slot.utils.mjs +222 -0
- package/dist/esm2022/lib/utils.mjs +10 -0
- package/dist/esm2022/services/resize-observer.service.mjs +152 -0
- package/dist/esm2022/services/scroll-position.service.mjs +124 -0
- package/dist/esm2022/types/frontend-tool.mjs +2 -0
- package/dist/esm2022/types/human-in-the-loop.mjs +2 -0
- package/dist/esm2022/utils/agent-context.utils.mjs +114 -0
- package/dist/esm2022/utils/agent.utils.mjs +204 -0
- package/dist/esm2022/utils/chat-config.utils.mjs +186 -0
- package/dist/esm2022/utils/copilotkit.utils.mjs +20 -0
- package/dist/esm2022/utils/frontend-tool.utils.mjs +228 -0
- package/dist/esm2022/utils/human-in-the-loop.utils.mjs +296 -0
- package/dist/fesm2022/copilotkitnext-angular.mjs +163 -164
- package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
- package/dist/styles.css +0 -27
- package/package.json +23 -20
- package/vitest.config.mts +32 -21
- package/.turbo/turbo-build.log +0 -39
- package/.turbo/turbo-check-types.log +0 -0
- package/.turbo/turbo-test.log +0 -71
- package/README-agent-context.md +0 -310
- package/ng-package.json +0 -19
- package/slots.md +0 -331
- package/src/components/chat/__tests__/copilot-chat-assistant-message.component.spec.ts +0 -282
- package/src/components/chat/__tests__/copilot-chat-input.component.spec.ts +0 -419
- package/src/components/chat/__tests__/copilot-chat-message-view.component.spec.ts +0 -372
- package/src/components/chat/__tests__/copilot-chat-user-message.component.spec.ts +0 -249
- package/src/components/chat/copilot-chat-assistant-message-buttons.component.ts +0 -292
- package/src/components/chat/copilot-chat-assistant-message-renderer.component.ts +0 -472
- package/src/components/chat/copilot-chat-assistant-message-toolbar.component.ts +0 -29
- package/src/components/chat/copilot-chat-assistant-message.component.ts +0 -463
- package/src/components/chat/copilot-chat-assistant-message.types.ts +0 -50
- package/src/components/chat/copilot-chat-audio-recorder.component.ts +0 -241
- package/src/components/chat/copilot-chat-buttons.component.ts +0 -308
- package/src/components/chat/copilot-chat-buttons.component.ts.bak +0 -471
- package/src/components/chat/copilot-chat-input-defaults.ts +0 -47
- package/src/components/chat/copilot-chat-input.component.ts +0 -512
- package/src/components/chat/copilot-chat-input.types.ts +0 -148
- package/src/components/chat/copilot-chat-message-view-cursor.component.ts +0 -51
- package/src/components/chat/copilot-chat-message-view.component.ts +0 -233
- package/src/components/chat/copilot-chat-message-view.types.ts +0 -39
- package/src/components/chat/copilot-chat-textarea.component.ts +0 -220
- package/src/components/chat/copilot-chat-tool-calls-view.component.ts +0 -261
- package/src/components/chat/copilot-chat-toolbar.component.ts +0 -35
- package/src/components/chat/copilot-chat-tools-menu.component.ts +0 -185
- package/src/components/chat/copilot-chat-user-message-branch-navigation.component.ts +0 -121
- package/src/components/chat/copilot-chat-user-message-buttons.component.ts +0 -170
- package/src/components/chat/copilot-chat-user-message-renderer.component.ts +0 -37
- package/src/components/chat/copilot-chat-user-message-toolbar.component.ts +0 -37
- package/src/components/chat/copilot-chat-user-message.component.ts +0 -247
- package/src/components/chat/copilot-chat-user-message.types.ts +0 -42
- package/src/components/chat/copilot-chat-view-disclaimer.component.ts +0 -51
- package/src/components/chat/copilot-chat-view-feather.component.ts +0 -47
- package/src/components/chat/copilot-chat-view-handlers.service.ts +0 -14
- package/src/components/chat/copilot-chat-view-input-container.component.ts +0 -87
- package/src/components/chat/copilot-chat-view-scroll-to-bottom-button.component.ts +0 -79
- package/src/components/chat/copilot-chat-view-scroll-view.component.ts +0 -322
- package/src/components/chat/copilot-chat-view.component.ts +0 -420
- package/src/components/chat/copilot-chat-view.types.ts +0 -52
- package/src/components/chat/copilot-chat.component.ts +0 -232
- package/src/components/copilotkit-tool-render.component.ts +0 -169
- package/src/core/__tests__/copilotkit.service.spec.ts +0 -1051
- package/src/core/__tests__/copilotkit.service.wildcard.spec.ts +0 -316
- package/src/core/chat-configuration/__tests__/chat-configuration.service.spec.ts +0 -287
- package/src/core/chat-configuration/chat-configuration.providers.ts +0 -71
- package/src/core/chat-configuration/chat-configuration.service.ts +0 -162
- package/src/core/chat-configuration/chat-configuration.types.ts +0 -57
- package/src/core/copilotkit.providers.ts +0 -59
- package/src/core/copilotkit.service.ts +0 -542
- package/src/core/copilotkit.types.ts +0 -132
- package/src/directives/__tests__/copilotkit-agent-context.directive.spec.ts +0 -384
- package/src/directives/__tests__/copilotkit-agent.directive.spec.ts +0 -253
- package/src/directives/__tests__/copilotkit-chat-config.directive.spec.ts +0 -385
- package/src/directives/__tests__/copilotkit-config.directive.spec.ts +0 -69
- package/src/directives/__tests__/copilotkit-frontend-tool-simple.directive.spec.ts +0 -60
- package/src/directives/__tests__/copilotkit-frontend-tool.directive.spec.ts +0 -108
- package/src/directives/__tests__/copilotkit-human-in-the-loop.directive.spec.ts +0 -452
- package/src/directives/copilotkit-agent-context.directive.ts +0 -138
- package/src/directives/copilotkit-agent.directive.ts +0 -225
- package/src/directives/copilotkit-chat-config.directive.ts +0 -241
- package/src/directives/copilotkit-config.directive.ts +0 -81
- package/src/directives/copilotkit-frontend-tool.directive.ts +0 -145
- package/src/directives/copilotkit-human-in-the-loop.directive.ts +0 -281
- package/src/directives/stick-to-bottom.directive.ts +0 -204
- package/src/index.ts +0 -105
- package/src/lib/directives/tooltip.directive.ts +0 -292
- package/src/lib/slots/__tests__/slot.utils.spec.ts +0 -377
- package/src/lib/slots/copilot-slot.component.ts +0 -135
- package/src/lib/slots/index.ts +0 -3
- package/src/lib/slots/slot.types.ts +0 -64
- package/src/lib/slots/slot.utils.ts +0 -289
- package/src/lib/utils.ts +0 -10
- package/src/public-api.ts +0 -1
- package/src/services/resize-observer.service.ts +0 -181
- package/src/services/scroll-position.service.ts +0 -169
- package/src/styles/globals.css +0 -266
- package/src/styles/index.css +0 -3
- package/src/test-setup.ts +0 -15
- package/src/testing/index.ts +0 -3
- package/src/testing/testing.utils.ts +0 -248
- package/src/types/frontend-tool.ts +0 -44
- package/src/types/human-in-the-loop.ts +0 -52
- package/src/utils/__tests__/agent.utils.spec.ts +0 -234
- package/src/utils/__tests__/chat-config.utils.spec.ts +0 -306
- package/src/utils/__tests__/frontend-tool-inject.spec.ts +0 -350
- package/src/utils/__tests__/frontend-tool-integration.spec.ts +0 -199
- package/src/utils/__tests__/frontend-tool.utils.spec.ts +0 -272
- package/src/utils/__tests__/human-in-the-loop.utils.spec.ts +0 -365
- package/src/utils/agent-context.utils.ts +0 -133
- package/src/utils/agent.utils.ts +0 -239
- package/src/utils/chat-config.utils.ts +0 -221
- package/src/utils/copilotkit.utils.ts +0 -20
- package/src/utils/frontend-tool.utils.ts +0 -266
- package/src/utils/human-in-the-loop.utils.ts +0 -359
- 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
|
-
});
|