@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,266 +0,0 @@
|
|
|
1
|
-
import { DestroyRef, inject } from '@angular/core';
|
|
2
|
-
import { CopilotKitService } from '../core/copilotkit.service';
|
|
3
|
-
import { AngularFrontendTool, AngularToolCallRender, ToolCallRender } from '../core/copilotkit.types';
|
|
4
|
-
import { z } from 'zod';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Explicitly adds a frontend tool to CopilotKit.
|
|
8
|
-
* Requires CopilotKitService to be passed as a parameter.
|
|
9
|
-
*
|
|
10
|
-
* @param service - The CopilotKitService instance
|
|
11
|
-
* @param tool - The tool to add
|
|
12
|
-
* @returns A cleanup function that removes the tool
|
|
13
|
-
*
|
|
14
|
-
* @example
|
|
15
|
-
* ```typescript
|
|
16
|
-
* export class MyComponent implements OnInit, OnDestroy {
|
|
17
|
-
* private cleanupFns: Array<() => void> = [];
|
|
18
|
-
*
|
|
19
|
-
* constructor(private copilotkit: CopilotKitService) {}
|
|
20
|
-
*
|
|
21
|
-
* ngOnInit() {
|
|
22
|
-
* const cleanup = addFrontendTool(this.copilotkit, {
|
|
23
|
-
* name: 'calculator',
|
|
24
|
-
* description: 'Performs calculations',
|
|
25
|
-
* parameters: z.object({
|
|
26
|
-
* expression: z.string()
|
|
27
|
-
* }),
|
|
28
|
-
* handler: async (args) => {
|
|
29
|
-
* return eval(args.expression);
|
|
30
|
-
* }
|
|
31
|
-
* });
|
|
32
|
-
*
|
|
33
|
-
* this.cleanupFns.push(cleanup);
|
|
34
|
-
* }
|
|
35
|
-
*
|
|
36
|
-
* ngOnDestroy() {
|
|
37
|
-
* this.cleanupFns.forEach(fn => fn());
|
|
38
|
-
* }
|
|
39
|
-
* }
|
|
40
|
-
* ```
|
|
41
|
-
*/
|
|
42
|
-
export function addFrontendTool<T extends Record<string, any> = Record<string, any>>(
|
|
43
|
-
service: CopilotKitService,
|
|
44
|
-
tool: AngularFrontendTool<T>
|
|
45
|
-
): () => void {
|
|
46
|
-
// Add the tool to CopilotKit
|
|
47
|
-
service.copilotkit.addTool(tool);
|
|
48
|
-
|
|
49
|
-
// Register the render if provided
|
|
50
|
-
if (tool.render) {
|
|
51
|
-
const currentRenders = service.currentRenderToolCalls();
|
|
52
|
-
const existingIndex = currentRenders.findIndex((r: ToolCallRender<unknown>) => r.name === tool.name);
|
|
53
|
-
|
|
54
|
-
if (existingIndex !== -1) {
|
|
55
|
-
console.error(`Tool with name '${tool.name}' already has a render. Skipping.`);
|
|
56
|
-
} else {
|
|
57
|
-
const renderEntry: AngularToolCallRender<T> = {
|
|
58
|
-
name: tool.name,
|
|
59
|
-
args: tool.parameters || (z.object({}) as unknown as z.ZodSchema<T>),
|
|
60
|
-
render: tool.render
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Return cleanup function
|
|
68
|
-
return () => {
|
|
69
|
-
removeFrontendTool(service, tool.name);
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Registers a frontend tool with CopilotKit and automatically removes it when the component/service is destroyed.
|
|
75
|
-
* Must be called within an injection context.
|
|
76
|
-
*
|
|
77
|
-
* @param tool - The tool to register
|
|
78
|
-
* @returns The tool name
|
|
79
|
-
*
|
|
80
|
-
* @example
|
|
81
|
-
* ```typescript
|
|
82
|
-
* export class MyComponent implements OnInit {
|
|
83
|
-
* ngOnInit() {
|
|
84
|
-
* // Automatically cleaned up on component destroy
|
|
85
|
-
* registerFrontendTool({
|
|
86
|
-
* name: 'search',
|
|
87
|
-
* description: 'Search for items',
|
|
88
|
-
* parameters: z.object({
|
|
89
|
-
* query: z.string()
|
|
90
|
-
* }),
|
|
91
|
-
* handler: async (args) => {
|
|
92
|
-
* return this.searchService.search(args.query);
|
|
93
|
-
* },
|
|
94
|
-
* render: SearchResultsComponent
|
|
95
|
-
* });
|
|
96
|
-
* }
|
|
97
|
-
* }
|
|
98
|
-
* ```
|
|
99
|
-
*/
|
|
100
|
-
export function registerFrontendTool<T extends Record<string, any> = Record<string, any>>(
|
|
101
|
-
tool: AngularFrontendTool<T>
|
|
102
|
-
): string {
|
|
103
|
-
const service = inject(CopilotKitService);
|
|
104
|
-
const destroyRef = inject(DestroyRef);
|
|
105
|
-
|
|
106
|
-
// Add the tool
|
|
107
|
-
service.copilotkit.addTool(tool);
|
|
108
|
-
|
|
109
|
-
// Register the render if provided
|
|
110
|
-
if (tool.render) {
|
|
111
|
-
const currentRenders = service.currentRenderToolCalls();
|
|
112
|
-
const existingIndex = currentRenders.findIndex((r: ToolCallRender<unknown>) => r.name === tool.name);
|
|
113
|
-
|
|
114
|
-
if (existingIndex !== -1) {
|
|
115
|
-
console.error(`Tool with name '${tool.name}' already has a render. Skipping.`);
|
|
116
|
-
} else {
|
|
117
|
-
const renderEntry: AngularToolCallRender<T> = {
|
|
118
|
-
name: tool.name,
|
|
119
|
-
args: tool.parameters || (z.object({}) as unknown as z.ZodSchema<T>),
|
|
120
|
-
render: tool.render
|
|
121
|
-
};
|
|
122
|
-
|
|
123
|
-
service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Register cleanup with Angular's DestroyRef
|
|
128
|
-
destroyRef.onDestroy(() => {
|
|
129
|
-
removeFrontendTool(service, tool.name);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
return tool.name;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Explicitly removes a frontend tool from CopilotKit.
|
|
137
|
-
*
|
|
138
|
-
* @param service - The CopilotKitService instance
|
|
139
|
-
* @param toolName - The name of the tool to remove
|
|
140
|
-
*
|
|
141
|
-
* @example
|
|
142
|
-
* ```typescript
|
|
143
|
-
* removeFrontendTool(this.copilotkit, 'calculator');
|
|
144
|
-
* ```
|
|
145
|
-
*/
|
|
146
|
-
export function removeFrontendTool(
|
|
147
|
-
service: CopilotKitService,
|
|
148
|
-
toolName: string
|
|
149
|
-
): void {
|
|
150
|
-
// Remove the tool
|
|
151
|
-
service.copilotkit.removeTool(toolName);
|
|
152
|
-
|
|
153
|
-
// Remove the render if it exists
|
|
154
|
-
const currentRenders = service.currentRenderToolCalls();
|
|
155
|
-
const filtered = currentRenders.filter((r: ToolCallRender<unknown>) => r.name !== toolName);
|
|
156
|
-
if (filtered.length !== currentRenders.length) {
|
|
157
|
-
service.setCurrentRenderToolCalls(filtered);
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Creates a frontend tool with dynamic parameters that can change over time.
|
|
163
|
-
* Uses Angular signals for reactivity.
|
|
164
|
-
*
|
|
165
|
-
* @param name - Tool name
|
|
166
|
-
* @param description - Tool description
|
|
167
|
-
* @param parameters - Zod schema for parameters
|
|
168
|
-
* @param handler - Signal or function that provides the handler
|
|
169
|
-
* @param render - Optional render component or template
|
|
170
|
-
* @returns Object with update and destroy methods
|
|
171
|
-
*
|
|
172
|
-
* @example
|
|
173
|
-
* ```typescript
|
|
174
|
-
* export class MyComponent {
|
|
175
|
-
* private toolConfig = signal({
|
|
176
|
-
* handler: async (args: any) => this.processDefault(args)
|
|
177
|
-
* });
|
|
178
|
-
*
|
|
179
|
-
* ngOnInit() {
|
|
180
|
-
* const tool = createDynamicFrontendTool(
|
|
181
|
-
* 'processor',
|
|
182
|
-
* 'Processes data',
|
|
183
|
-
* z.object({ data: z.string() }),
|
|
184
|
-
* () => this.toolConfig().handler
|
|
185
|
-
* );
|
|
186
|
-
*
|
|
187
|
-
* // Later, update the handler
|
|
188
|
-
* this.toolConfig.set({
|
|
189
|
-
* handler: async (args: any) => this.processAdvanced(args)
|
|
190
|
-
* });
|
|
191
|
-
* tool.update();
|
|
192
|
-
* }
|
|
193
|
-
* }
|
|
194
|
-
* ```
|
|
195
|
-
*/
|
|
196
|
-
export function createDynamicFrontendTool<T extends Record<string, any> = Record<string, any>>(
|
|
197
|
-
name: string,
|
|
198
|
-
description: string | (() => string),
|
|
199
|
-
parameters: z.ZodSchema<T>,
|
|
200
|
-
handler: () => ((args: T) => Promise<any>),
|
|
201
|
-
render?: () => any
|
|
202
|
-
): { update: () => void; destroy: () => void } {
|
|
203
|
-
const service = inject(CopilotKitService);
|
|
204
|
-
const destroyRef = inject(DestroyRef);
|
|
205
|
-
|
|
206
|
-
let isRegistered = false;
|
|
207
|
-
|
|
208
|
-
const update = () => {
|
|
209
|
-
// Remove old tool if registered
|
|
210
|
-
if (isRegistered) {
|
|
211
|
-
service.copilotkit.removeTool(name);
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Create new tool configuration
|
|
215
|
-
const desc = typeof description === 'function' ? description() : description;
|
|
216
|
-
const currentHandler = handler();
|
|
217
|
-
const currentRender = render ? render() : undefined;
|
|
218
|
-
|
|
219
|
-
const tool: AngularFrontendTool<T> = {
|
|
220
|
-
name,
|
|
221
|
-
description: desc,
|
|
222
|
-
parameters,
|
|
223
|
-
handler: currentHandler,
|
|
224
|
-
render: currentRender
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
// Add the tool
|
|
228
|
-
service.copilotkit.addTool(tool);
|
|
229
|
-
|
|
230
|
-
// Update render if provided
|
|
231
|
-
if (currentRender) {
|
|
232
|
-
const currentRenders = service.currentRenderToolCalls();
|
|
233
|
-
const renderEntry: AngularToolCallRender<T> = {
|
|
234
|
-
name: name,
|
|
235
|
-
args: parameters,
|
|
236
|
-
render: currentRender
|
|
237
|
-
};
|
|
238
|
-
|
|
239
|
-
const existingIndex = currentRenders.findIndex((r: ToolCallRender<unknown>) => r.name === name);
|
|
240
|
-
if (existingIndex !== -1) {
|
|
241
|
-
const updated = [...currentRenders];
|
|
242
|
-
updated[existingIndex] = renderEntry;
|
|
243
|
-
service.setCurrentRenderToolCalls(updated);
|
|
244
|
-
} else {
|
|
245
|
-
service.setCurrentRenderToolCalls([...currentRenders, renderEntry]);
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
isRegistered = true;
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
const destroy = () => {
|
|
253
|
-
if (isRegistered) {
|
|
254
|
-
removeFrontendTool(service, name);
|
|
255
|
-
isRegistered = false;
|
|
256
|
-
}
|
|
257
|
-
};
|
|
258
|
-
|
|
259
|
-
// Initial setup
|
|
260
|
-
update();
|
|
261
|
-
|
|
262
|
-
// Register cleanup
|
|
263
|
-
destroyRef.onDestroy(destroy);
|
|
264
|
-
|
|
265
|
-
return { update, destroy };
|
|
266
|
-
}
|
|
@@ -1,359 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
DestroyRef,
|
|
3
|
-
inject,
|
|
4
|
-
signal,
|
|
5
|
-
Signal,
|
|
6
|
-
Type,
|
|
7
|
-
TemplateRef
|
|
8
|
-
} from '@angular/core';
|
|
9
|
-
import { CopilotKitService } from '../core/copilotkit.service';
|
|
10
|
-
import {
|
|
11
|
-
AngularHumanInTheLoop,
|
|
12
|
-
ToolCallStatus,
|
|
13
|
-
HumanInTheLoopState,
|
|
14
|
-
HumanInTheLoopProps,
|
|
15
|
-
AngularFrontendTool
|
|
16
|
-
} from '../core/copilotkit.types';
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Registers a human-in-the-loop tool that requires user interaction.
|
|
20
|
-
* Must be called within an injection context.
|
|
21
|
-
* Automatically cleans up when the component/service is destroyed.
|
|
22
|
-
*
|
|
23
|
-
* @param tool - The human-in-the-loop tool configuration
|
|
24
|
-
* @returns The tool ID
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```typescript
|
|
28
|
-
* export class ApprovalComponent {
|
|
29
|
-
* toolId = registerHumanInTheLoop({
|
|
30
|
-
* name: 'requireApproval',
|
|
31
|
-
* description: 'Requires user approval',
|
|
32
|
-
* args: z.object({ action: z.string() }),
|
|
33
|
-
* render: ApprovalDialogComponent
|
|
34
|
-
* });
|
|
35
|
-
* }
|
|
36
|
-
* ```
|
|
37
|
-
*/
|
|
38
|
-
export function registerHumanInTheLoop<T extends Record<string, any> = Record<string, any>>(
|
|
39
|
-
tool: AngularHumanInTheLoop<T>
|
|
40
|
-
): string {
|
|
41
|
-
const service = inject(CopilotKitService);
|
|
42
|
-
const destroyRef = inject(DestroyRef);
|
|
43
|
-
|
|
44
|
-
// Create state management
|
|
45
|
-
const statusSignal = signal<ToolCallStatus>(ToolCallStatus.InProgress);
|
|
46
|
-
let resolvePromise: ((result: unknown) => void) | null = null;
|
|
47
|
-
|
|
48
|
-
// Create respond function
|
|
49
|
-
const respond = async (result: unknown): Promise<void> => {
|
|
50
|
-
if (resolvePromise) {
|
|
51
|
-
resolvePromise(result);
|
|
52
|
-
statusSignal.set(ToolCallStatus.Complete);
|
|
53
|
-
resolvePromise = null;
|
|
54
|
-
}
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
// Create handler that returns a Promise
|
|
58
|
-
const handler = async (_args: T): Promise<unknown> => {
|
|
59
|
-
return new Promise((resolve) => {
|
|
60
|
-
statusSignal.set(ToolCallStatus.Executing);
|
|
61
|
-
resolvePromise = resolve;
|
|
62
|
-
});
|
|
63
|
-
};
|
|
64
|
-
|
|
65
|
-
// Create enhanced render function
|
|
66
|
-
const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
|
|
67
|
-
|
|
68
|
-
// Create the frontend tool
|
|
69
|
-
const frontendTool: AngularFrontendTool<T> = {
|
|
70
|
-
...tool,
|
|
71
|
-
handler,
|
|
72
|
-
render: enhancedRender
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
// Add the tool (returns void, so we use the tool name as ID)
|
|
76
|
-
service.copilotkit.addTool(frontendTool);
|
|
77
|
-
const toolId = frontendTool.name;
|
|
78
|
-
|
|
79
|
-
// Register tool render if provided
|
|
80
|
-
if (frontendTool.render && tool.parameters) {
|
|
81
|
-
service.registerToolRender(frontendTool.name, {
|
|
82
|
-
name: frontendTool.name,
|
|
83
|
-
args: tool.parameters,
|
|
84
|
-
render: frontendTool.render
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Cleanup on destroy
|
|
89
|
-
destroyRef.onDestroy(() => {
|
|
90
|
-
service.copilotkit.removeTool(toolId);
|
|
91
|
-
if (frontendTool.render) {
|
|
92
|
-
service.unregisterToolRender(frontendTool.name);
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
return toolId;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Adds a human-in-the-loop tool with explicit service parameter.
|
|
101
|
-
* Returns a cleanup function.
|
|
102
|
-
*
|
|
103
|
-
* @param service - The CopilotKitService instance
|
|
104
|
-
* @param tool - The human-in-the-loop tool configuration
|
|
105
|
-
* @returns Cleanup function to remove the tool
|
|
106
|
-
*
|
|
107
|
-
* @example
|
|
108
|
-
* ```typescript
|
|
109
|
-
* export class MyComponent implements OnInit, OnDestroy {
|
|
110
|
-
* private cleanup?: () => void;
|
|
111
|
-
*
|
|
112
|
-
* constructor(private copilotkit: CopilotKitService) {}
|
|
113
|
-
*
|
|
114
|
-
* ngOnInit() {
|
|
115
|
-
* this.cleanup = addHumanInTheLoop(this.copilotkit, {
|
|
116
|
-
* name: 'requireApproval',
|
|
117
|
-
* description: 'Requires user approval',
|
|
118
|
-
* args: z.object({ action: z.string() }),
|
|
119
|
-
* render: ApprovalDialogComponent
|
|
120
|
-
* });
|
|
121
|
-
* }
|
|
122
|
-
*
|
|
123
|
-
* ngOnDestroy() {
|
|
124
|
-
* this.cleanup?.();
|
|
125
|
-
* }
|
|
126
|
-
* }
|
|
127
|
-
* ```
|
|
128
|
-
*/
|
|
129
|
-
export function addHumanInTheLoop<T extends Record<string, any> = Record<string, any>>(
|
|
130
|
-
service: CopilotKitService,
|
|
131
|
-
tool: AngularHumanInTheLoop<T>
|
|
132
|
-
): () => void {
|
|
133
|
-
// Create state management
|
|
134
|
-
const statusSignal = signal<ToolCallStatus>(ToolCallStatus.InProgress);
|
|
135
|
-
let resolvePromise: ((result: unknown) => void) | null = null;
|
|
136
|
-
|
|
137
|
-
// Create respond function
|
|
138
|
-
const respond = async (result: unknown): Promise<void> => {
|
|
139
|
-
if (resolvePromise) {
|
|
140
|
-
resolvePromise(result);
|
|
141
|
-
statusSignal.set(ToolCallStatus.Complete);
|
|
142
|
-
resolvePromise = null;
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
// Create handler that returns a Promise
|
|
147
|
-
const handler = async (_args: T): Promise<unknown> => {
|
|
148
|
-
return new Promise((resolve) => {
|
|
149
|
-
statusSignal.set(ToolCallStatus.Executing);
|
|
150
|
-
resolvePromise = resolve;
|
|
151
|
-
});
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
// Create enhanced render function
|
|
155
|
-
const enhancedRender = createEnhancedRender(tool.render, statusSignal, respond);
|
|
156
|
-
|
|
157
|
-
// Create the frontend tool
|
|
158
|
-
const frontendTool: AngularFrontendTool<T> = {
|
|
159
|
-
...tool,
|
|
160
|
-
handler,
|
|
161
|
-
render: enhancedRender
|
|
162
|
-
};
|
|
163
|
-
|
|
164
|
-
// Add the tool (returns void, so we use the tool name as ID)
|
|
165
|
-
service.copilotkit.addTool(frontendTool);
|
|
166
|
-
const toolId = frontendTool.name;
|
|
167
|
-
|
|
168
|
-
// Register tool render if provided
|
|
169
|
-
if (frontendTool.render && tool.parameters) {
|
|
170
|
-
service.registerToolRender(frontendTool.name, {
|
|
171
|
-
name: frontendTool.name,
|
|
172
|
-
args: tool.parameters,
|
|
173
|
-
render: frontendTool.render
|
|
174
|
-
});
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
// Return cleanup function
|
|
178
|
-
return () => {
|
|
179
|
-
service.copilotkit.removeTool(toolId);
|
|
180
|
-
if (frontendTool.render) {
|
|
181
|
-
service.unregisterToolRender(frontendTool.name);
|
|
182
|
-
}
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Creates a human-in-the-loop tool with dynamic update capabilities.
|
|
188
|
-
*
|
|
189
|
-
* @param service - The CopilotKitService instance
|
|
190
|
-
* @param tool - The human-in-the-loop tool configuration
|
|
191
|
-
* @returns Object with status signal, update and destroy methods
|
|
192
|
-
*
|
|
193
|
-
* @example
|
|
194
|
-
* ```typescript
|
|
195
|
-
* export class MyComponent {
|
|
196
|
-
* humanInTheLoop = createHumanInTheLoop(this.copilotkit, {
|
|
197
|
-
* name: 'requireApproval',
|
|
198
|
-
* description: 'Requires user approval',
|
|
199
|
-
* args: z.object({ action: z.string() }),
|
|
200
|
-
* render: ApprovalDialogComponent
|
|
201
|
-
* });
|
|
202
|
-
*
|
|
203
|
-
* updateDescription(newDesc: string) {
|
|
204
|
-
* this.humanInTheLoop.update({ description: newDesc });
|
|
205
|
-
* }
|
|
206
|
-
*
|
|
207
|
-
* ngOnDestroy() {
|
|
208
|
-
* this.humanInTheLoop.destroy();
|
|
209
|
-
* }
|
|
210
|
-
* }
|
|
211
|
-
* ```
|
|
212
|
-
*/
|
|
213
|
-
export function createHumanInTheLoop<T extends Record<string, any> = Record<string, any>>(
|
|
214
|
-
service: CopilotKitService,
|
|
215
|
-
tool: AngularHumanInTheLoop<T>
|
|
216
|
-
): HumanInTheLoopState & { update: (updates: Partial<AngularHumanInTheLoop<T>>) => void } {
|
|
217
|
-
// Create state management
|
|
218
|
-
const statusSignal = signal<ToolCallStatus>(ToolCallStatus.InProgress);
|
|
219
|
-
let currentTool = { ...tool };
|
|
220
|
-
let toolId: string = '';
|
|
221
|
-
let resolvePromise: ((result: unknown) => void) | null = null;
|
|
222
|
-
|
|
223
|
-
// Create respond function
|
|
224
|
-
const respond = async (result: unknown): Promise<void> => {
|
|
225
|
-
if (resolvePromise) {
|
|
226
|
-
resolvePromise(result);
|
|
227
|
-
statusSignal.set(ToolCallStatus.Complete);
|
|
228
|
-
resolvePromise = null;
|
|
229
|
-
}
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// Create handler that returns a Promise
|
|
233
|
-
const handler = async (_args: T): Promise<unknown> => {
|
|
234
|
-
return new Promise((resolve) => {
|
|
235
|
-
statusSignal.set(ToolCallStatus.Executing);
|
|
236
|
-
resolvePromise = resolve;
|
|
237
|
-
});
|
|
238
|
-
};
|
|
239
|
-
|
|
240
|
-
// Function to add the tool
|
|
241
|
-
const addTool = () => {
|
|
242
|
-
// Create enhanced render function
|
|
243
|
-
const enhancedRender = createEnhancedRender(currentTool.render, statusSignal, respond);
|
|
244
|
-
|
|
245
|
-
// Create the frontend tool
|
|
246
|
-
const frontendTool: AngularFrontendTool<T> = {
|
|
247
|
-
...currentTool,
|
|
248
|
-
handler,
|
|
249
|
-
render: enhancedRender
|
|
250
|
-
};
|
|
251
|
-
|
|
252
|
-
// Add tool (returns void, so we use the tool name as ID)
|
|
253
|
-
service.copilotkit.addTool(frontendTool);
|
|
254
|
-
toolId = frontendTool.name;
|
|
255
|
-
|
|
256
|
-
// Register tool render if provided
|
|
257
|
-
if (frontendTool.render && currentTool.parameters) {
|
|
258
|
-
service.registerToolRender(frontendTool.name, {
|
|
259
|
-
name: frontendTool.name,
|
|
260
|
-
args: currentTool.parameters,
|
|
261
|
-
render: frontendTool.render
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
|
|
266
|
-
// Initialize the tool
|
|
267
|
-
addTool();
|
|
268
|
-
|
|
269
|
-
return {
|
|
270
|
-
status: statusSignal.asReadonly(),
|
|
271
|
-
toolId,
|
|
272
|
-
update: (updates: Partial<AngularHumanInTheLoop<T>>) => {
|
|
273
|
-
// Remove old tool
|
|
274
|
-
service.copilotkit.removeTool(toolId);
|
|
275
|
-
if (currentTool.render) {
|
|
276
|
-
service.unregisterToolRender(currentTool.name);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
// Update tool configuration
|
|
280
|
-
currentTool = { ...currentTool, ...updates };
|
|
281
|
-
|
|
282
|
-
// Re-add with new configuration
|
|
283
|
-
addTool();
|
|
284
|
-
},
|
|
285
|
-
destroy: () => {
|
|
286
|
-
service.copilotkit.removeTool(toolId);
|
|
287
|
-
if (currentTool.render) {
|
|
288
|
-
service.unregisterToolRender(currentTool.name);
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
/**
|
|
295
|
-
* Creates an enhanced render function that injects the respond function
|
|
296
|
-
* when the status is 'executing'.
|
|
297
|
-
*/
|
|
298
|
-
function createEnhancedRender<T extends Record<string, any>>(
|
|
299
|
-
originalRender: Type<any> | TemplateRef<HumanInTheLoopProps<T>>,
|
|
300
|
-
_statusSignal: Signal<ToolCallStatus>,
|
|
301
|
-
_respond: (result: unknown) => Promise<void>
|
|
302
|
-
): Type<any> | TemplateRef<any> {
|
|
303
|
-
// For component classes, we need to create a wrapper
|
|
304
|
-
if (isComponentClass(originalRender)) {
|
|
305
|
-
// Return a wrapper component factory
|
|
306
|
-
// This is complex in Angular and would require dynamic component creation
|
|
307
|
-
// For now, we'll return the original and rely on prop injection
|
|
308
|
-
return originalRender;
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
// For templates, we can't easily wrap them
|
|
312
|
-
// The template context will be enhanced in the render component
|
|
313
|
-
return originalRender;
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/**
|
|
317
|
-
* Helper function to check if a value is a component class
|
|
318
|
-
*/
|
|
319
|
-
function isComponentClass(value: any): value is Type<any> {
|
|
320
|
-
return typeof value === 'function' && value.prototype;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
/**
|
|
324
|
-
* Enhanced component wrapper for human-in-the-loop.
|
|
325
|
-
* This would be used internally by the tool render component to inject
|
|
326
|
-
* the respond function based on status.
|
|
327
|
-
*
|
|
328
|
-
* @internal
|
|
329
|
-
*/
|
|
330
|
-
export function enhancePropsForHumanInTheLoop<T>(
|
|
331
|
-
props: HumanInTheLoopProps<T>,
|
|
332
|
-
status: ToolCallStatus,
|
|
333
|
-
respond?: (result: unknown) => Promise<void>
|
|
334
|
-
): HumanInTheLoopProps<T> {
|
|
335
|
-
if (status === ToolCallStatus.Executing && respond) {
|
|
336
|
-
return {
|
|
337
|
-
...props,
|
|
338
|
-
status: ToolCallStatus.Executing,
|
|
339
|
-
respond
|
|
340
|
-
} as HumanInTheLoopProps<T>;
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
if (status === ToolCallStatus.Complete) {
|
|
344
|
-
return {
|
|
345
|
-
...props,
|
|
346
|
-
status: ToolCallStatus.Complete,
|
|
347
|
-
result: typeof props.result === 'string' ? props.result : '',
|
|
348
|
-
respond: undefined
|
|
349
|
-
} as HumanInTheLoopProps<T>;
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// InProgress
|
|
353
|
-
return {
|
|
354
|
-
...props,
|
|
355
|
-
status: ToolCallStatus.InProgress,
|
|
356
|
-
result: undefined,
|
|
357
|
-
respond: undefined
|
|
358
|
-
} as HumanInTheLoopProps<T>;
|
|
359
|
-
}
|
package/tsconfig.spec.json
DELETED