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