@copilotkitnext/angular 1.52.0-next.8 → 1.52.0
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 +225 -432
- package/dist/README.md +225 -432
- package/dist/fesm2022/copilotkitnext-angular.mjs +312 -161
- package/dist/fesm2022/copilotkitnext-angular.mjs.map +1 -1
- package/dist/lib/agent.d.ts +20 -20
- package/dist/lib/components/chat/copilot-chat-assistant-message.d.ts +46 -46
- package/dist/lib/components/chat/copilot-chat-message-view.d.ts +126 -126
- package/dist/lib/components/chat/copilot-chat-tool-calls-view.d.ts +23 -23
- package/dist/lib/components/chat/copilot-chat-user-message-branch-navigation.d.ts +6 -6
- package/dist/lib/components/chat/copilot-chat-user-message.d.ts +6 -6
- package/dist/lib/components/chat/copilot-chat-view-scroll-view.d.ts +18 -18
- package/dist/lib/components/chat/copilot-chat-view.d.ts +54 -54
- package/dist/lib/components/chat/copilot-chat.d.ts +18 -18
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/copilotkit.d.ts +6 -1
- package/dist/lib/license-watermark.d.ts +1 -0
- package/dist/lib/render-tool-calls.d.ts +23 -23
- package/dist/styles.css +3 -0
- package/package.json +18 -18
- package/dist/esm2022/copilotkitnext-angular.mjs +0 -5
- package/dist/esm2022/index.mjs +0 -2
- package/dist/esm2022/lib/agent-context.mjs +0 -25
- package/dist/esm2022/lib/agent.mjs +0 -73
- package/dist/esm2022/lib/chat-config.mjs +0 -35
- package/dist/esm2022/lib/chat-state.mjs +0 -18
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-buttons.mjs +0 -344
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-renderer.mjs +0 -260
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message-toolbar.mjs +0 -22
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message.mjs +0 -415
- package/dist/esm2022/lib/components/chat/copilot-chat-assistant-message.types.mjs +0 -2
- package/dist/esm2022/lib/components/chat/copilot-chat-audio-recorder.mjs +0 -196
- package/dist/esm2022/lib/components/chat/copilot-chat-buttons.mjs +0 -299
- package/dist/esm2022/lib/components/chat/copilot-chat-input-defaults.mjs +0 -39
- package/dist/esm2022/lib/components/chat/copilot-chat-input.mjs +0 -634
- package/dist/esm2022/lib/components/chat/copilot-chat-input.types.mjs +0 -10
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view-cursor.mjs +0 -27
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view.mjs +0 -269
- package/dist/esm2022/lib/components/chat/copilot-chat-message-view.types.mjs +0 -2
- package/dist/esm2022/lib/components/chat/copilot-chat-textarea.mjs +0 -139
- package/dist/esm2022/lib/components/chat/copilot-chat-tool-calls-view.mjs +0 -36
- package/dist/esm2022/lib/components/chat/copilot-chat-toolbar.mjs +0 -20
- package/dist/esm2022/lib/components/chat/copilot-chat-tools-menu.mjs +0 -203
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-branch-navigation.mjs +0 -118
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-buttons.mjs +0 -182
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-renderer.mjs +0 -28
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message-toolbar.mjs +0 -25
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message.mjs +0 -328
- package/dist/esm2022/lib/components/chat/copilot-chat-user-message.types.mjs +0 -2
- package/dist/esm2022/lib/components/chat/copilot-chat-view-disclaimer.mjs +0 -48
- package/dist/esm2022/lib/components/chat/copilot-chat-view-feather.mjs +0 -41
- package/dist/esm2022/lib/components/chat/copilot-chat-view-handlers.mjs +0 -19
- package/dist/esm2022/lib/components/chat/copilot-chat-view-input-container.mjs +0 -96
- package/dist/esm2022/lib/components/chat/copilot-chat-view-scroll-to-bottom-button.mjs +0 -89
- package/dist/esm2022/lib/components/chat/copilot-chat-view-scroll-view.mjs +0 -456
- package/dist/esm2022/lib/components/chat/copilot-chat-view.mjs +0 -404
- package/dist/esm2022/lib/components/chat/copilot-chat-view.types.mjs +0 -2
- package/dist/esm2022/lib/components/chat/copilot-chat.mjs +0 -165
- package/dist/esm2022/lib/config.mjs +0 -9
- package/dist/esm2022/lib/copilotkit.mjs +0 -125
- package/dist/esm2022/lib/directives/copilotkit-agent-context.mjs +0 -130
- package/dist/esm2022/lib/directives/stick-to-bottom.mjs +0 -170
- package/dist/esm2022/lib/directives/tooltip.mjs +0 -217
- package/dist/esm2022/lib/human-in-the-loop.mjs +0 -19
- package/dist/esm2022/lib/render-tool-calls.mjs +0 -167
- package/dist/esm2022/lib/resize-observer.mjs +0 -152
- package/dist/esm2022/lib/scroll-position.mjs +0 -123
- package/dist/esm2022/lib/slots/copilot-slot.mjs +0 -156
- package/dist/esm2022/lib/slots/index.mjs +0 -4
- package/dist/esm2022/lib/slots/slot.types.mjs +0 -6
- package/dist/esm2022/lib/slots/slot.utils.mjs +0 -235
- package/dist/esm2022/lib/tools.mjs +0 -31
- package/dist/esm2022/lib/utils.mjs +0 -10
- package/dist/esm2022/public-api.mjs +0 -48
package/README.md
CHANGED
|
@@ -1,534 +1,327 @@
|
|
|
1
1
|
# CopilotKit for Angular
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
1. **Install**: `pnpm add @copilotkitnext/angular`
|
|
8
|
-
2. **Add styles**: Add `@copilotkitnext/angular/styles.css` to your Angular app styles array or `@import "@copilotkitnext/angular/styles.css";` in a global stylesheet
|
|
9
|
-
3. **Provide CopilotKit**: Set the runtime URL and optional labels via providers
|
|
10
|
-
4. **Use the chat**: Drop `<copilot-chat />` into any template
|
|
3
|
+
Angular bindings for CopilotKit core and AG-UI agents. This package provides services, directives, and utilities for building custom, headless Copilot UIs.
|
|
11
4
|
|
|
12
5
|
## Installation
|
|
13
6
|
|
|
14
|
-
### Package Installation
|
|
15
|
-
|
|
16
|
-
Install `@copilotkitnext/angular` in your Angular app (supports Angular 18 and 19):
|
|
17
|
-
|
|
18
7
|
```bash
|
|
19
|
-
# pnpm (recommended)
|
|
20
|
-
pnpm add @copilotkitnext/angular
|
|
21
|
-
|
|
22
8
|
# npm
|
|
23
|
-
npm install @copilotkitnext/angular
|
|
24
|
-
|
|
25
|
-
# yarn
|
|
26
|
-
yarn add @copilotkitnext/angular
|
|
9
|
+
npm install @copilotkitnext/{core,angular}
|
|
27
10
|
```
|
|
28
11
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
Ensure these are present (matching your Angular major):
|
|
32
|
-
|
|
33
|
-
- `@angular/core`
|
|
34
|
-
- `@angular/common`
|
|
35
|
-
- `@angular/cdk` (use `^18` with Angular 18, `^19` with Angular 19)
|
|
12
|
+
- `@angular/core` and `@angular/common` (19+)
|
|
13
|
+
- `@angular/cdk` (match your Angular major)
|
|
36
14
|
- `rxjs`
|
|
37
|
-
- `tslib`
|
|
38
|
-
|
|
39
|
-
### Styles
|
|
40
15
|
|
|
41
|
-
|
|
16
|
+
## Quick start
|
|
42
17
|
|
|
43
|
-
|
|
18
|
+
### 1) Provide CopilotKit
|
|
44
19
|
|
|
45
|
-
|
|
46
|
-
"styles": [
|
|
47
|
-
"@copilotkitnext/angular/styles.css",
|
|
48
|
-
"src/styles.css"
|
|
49
|
-
]
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
**Option 2:** In your global stylesheet:
|
|
53
|
-
|
|
54
|
-
```css
|
|
55
|
-
@import "@copilotkitnext/angular/styles.css";
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
## App Wiring (Providers)
|
|
20
|
+
Configure runtime and tools in your app config:
|
|
59
21
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
```typescript
|
|
65
|
-
import {
|
|
66
|
-
provideCopilotKit,
|
|
67
|
-
provideCopilotChatConfiguration,
|
|
68
|
-
} from "@copilotkitnext/angular";
|
|
22
|
+
```ts
|
|
23
|
+
import { ApplicationConfig } from "@angular/core";
|
|
24
|
+
import { provideCopilotKit } from "@copilotkitnext/angular";
|
|
69
25
|
|
|
70
26
|
export const appConfig: ApplicationConfig = {
|
|
71
27
|
providers: [
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
labels: {
|
|
78
|
-
chatInputPlaceholder: "Ask me anything...",
|
|
79
|
-
chatDisclaimerText: "AI responses may need verification.",
|
|
80
|
-
},
|
|
28
|
+
provideCopilotKit({
|
|
29
|
+
licenseKey: "ck_pub_your_public_api_key",
|
|
30
|
+
runtimeUrl: "http://localhost:3001/api/copilotkit",
|
|
31
|
+
headers: { Authorization: "Bearer ..." },
|
|
32
|
+
properties: { app: "demo" },
|
|
81
33
|
}),
|
|
82
34
|
],
|
|
83
35
|
};
|
|
84
36
|
```
|
|
85
37
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
You can declare the CopilotKit runtime endpoint directly in templates via the `CopilotKitConfigDirective`.
|
|
89
|
-
|
|
90
|
-
### Component Template Example:
|
|
91
|
-
|
|
92
|
-
```html
|
|
93
|
-
<div
|
|
94
|
-
[copilotkitConfig]="{ runtimeUrl: runtimeUrl }"
|
|
95
|
-
style="display:block;height:100vh"
|
|
96
|
-
>
|
|
97
|
-
<copilot-chat></copilot-chat>
|
|
98
|
-
</div>
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Component Class:
|
|
102
|
-
|
|
103
|
-
```typescript
|
|
104
|
-
export class AppComponent {
|
|
105
|
-
runtimeUrl = "http://localhost:3001/api/copilotkit";
|
|
106
|
-
}
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
## Using the Chat Component
|
|
110
|
-
|
|
111
|
-
### Minimal Usage:
|
|
112
|
-
|
|
113
|
-
```html
|
|
114
|
-
<copilot-chat></copilot-chat>
|
|
115
|
-
```
|
|
38
|
+
### 2) Build a custom UI with `injectAgentStore`
|
|
116
39
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
### Behavior:
|
|
124
|
-
|
|
125
|
-
- If `agentId` is omitted, the component uses the default agent (ID: `default`)
|
|
126
|
-
|
|
127
|
-
## Custom Input Components (Angular)
|
|
128
|
-
|
|
129
|
-
When building custom input components for CopilotKit Angular, use the service-based pattern with `CopilotChatConfigurationService` for message submission. This is the idiomatic Angular approach leveraging dependency injection.
|
|
130
|
-
|
|
131
|
-
### Service-Based Custom Input Example:
|
|
132
|
-
|
|
133
|
-
```typescript
|
|
134
|
-
import { Component } from "@angular/core";
|
|
135
|
-
import { FormsModule } from "@angular/forms";
|
|
136
|
-
import { CopilotChatConfigurationService } from "@copilotkitnext/angular";
|
|
40
|
+
```ts
|
|
41
|
+
import { Component, inject, signal } from "@angular/core";
|
|
42
|
+
import { Message } from "@ag-ui/client";
|
|
43
|
+
import { CopilotKit, injectAgentStore } from "@copilotkitnext/angular";
|
|
44
|
+
import { randomUUID } from "@copilotkitnext/shared";
|
|
137
45
|
|
|
138
46
|
@Component({
|
|
139
|
-
selector: "my-custom-input",
|
|
140
|
-
standalone: true,
|
|
141
|
-
imports: [FormsModule],
|
|
142
47
|
template: `
|
|
143
|
-
|
|
144
|
-
<
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
/>
|
|
149
|
-
<button (click)="submitMessage()">Send</button>
|
|
150
|
-
</div>
|
|
151
|
-
`,
|
|
152
|
-
})
|
|
153
|
-
export class MyCustomInputComponent {
|
|
154
|
-
inputValue = "";
|
|
155
|
-
|
|
156
|
-
constructor(private chat: CopilotChatConfigurationService) {}
|
|
157
|
-
|
|
158
|
-
submitMessage() {
|
|
159
|
-
const value = this.inputValue.trim();
|
|
160
|
-
if (value) {
|
|
161
|
-
// Use the service to submit the message
|
|
162
|
-
this.chat.submitInput(value);
|
|
163
|
-
this.inputValue = "";
|
|
48
|
+
@for (let message of messages(); track message.id) {
|
|
49
|
+
<div>
|
|
50
|
+
<em>{{ message.role }}</em>
|
|
51
|
+
<p>{{ message.content }}</p>
|
|
52
|
+
</div>
|
|
164
53
|
}
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Using the Custom Input Component:
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
import { Component } from "@angular/core";
|
|
173
|
-
import { CopilotChatViewComponent } from "@copilotkitnext/angular";
|
|
174
|
-
import { MyCustomInputComponent } from "./my-custom-input.component";
|
|
175
54
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
<
|
|
182
|
-
[messages]="messages"
|
|
183
|
-
[inputComponent]="customInputComponent"
|
|
184
|
-
>
|
|
185
|
-
</copilot-chat-view>
|
|
55
|
+
<input
|
|
56
|
+
[value]="input()"
|
|
57
|
+
(input)="input.set($any($event.target).value)"
|
|
58
|
+
(keyup.enter)="send()"
|
|
59
|
+
/>
|
|
60
|
+
<button (click)="send()" [disabled]="store().isRunning()">Send</button>
|
|
186
61
|
`,
|
|
187
62
|
})
|
|
188
|
-
export class
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
```
|
|
63
|
+
export class HeadlessChatComponent {
|
|
64
|
+
readonly copilotKit = inject(CopilotKit);
|
|
65
|
+
readonly store = injectAgentStore("default");
|
|
66
|
+
readonly messages = this.store().messages;
|
|
193
67
|
|
|
194
|
-
|
|
68
|
+
readonly input = signal("");
|
|
195
69
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
- **Type safety**: Full TypeScript support with proper type inference
|
|
70
|
+
async send() {
|
|
71
|
+
const content = this.input().trim();
|
|
72
|
+
if (!content) return;
|
|
200
73
|
|
|
201
|
-
|
|
74
|
+
const agent = this.store().agent;
|
|
202
75
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
onSubmitInput: handleSubmit,
|
|
209
|
-
onChangeInput: handleChange
|
|
210
|
-
}"
|
|
211
|
-
>
|
|
212
|
-
<copilot-chat></copilot-chat>
|
|
213
|
-
</div>
|
|
214
|
-
```
|
|
76
|
+
agent.addMessage({
|
|
77
|
+
id: randomUUID(),
|
|
78
|
+
role: "user",
|
|
79
|
+
content,
|
|
80
|
+
});
|
|
215
81
|
|
|
216
|
-
|
|
217
|
-
export class ChatComponent {
|
|
218
|
-
handleSubmit = (value: string) => {
|
|
219
|
-
console.log("Message submitted:", value);
|
|
220
|
-
};
|
|
82
|
+
this.input.set("");
|
|
221
83
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
};
|
|
84
|
+
await this.copilotKit.core.runAgent({ agent });
|
|
85
|
+
}
|
|
225
86
|
}
|
|
226
87
|
```
|
|
227
88
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
- **Agent model**: CopilotKit uses AG-UI's `AbstractAgent` interface (package `@ag-ui/client`)
|
|
231
|
-
- **Frontend vs backend**:
|
|
232
|
-
- **Backend (runtime)**: Host your real agents. You can use any AG-UI agent on the server
|
|
233
|
-
- **Frontend (Angular app)**: Discovers remote agents from the runtime automatically, and can also host local in-browser agents if desired
|
|
234
|
-
- **Default agent**: The ID `default` is special; when present, it is used by `<copilot-chat>` if no `agentId` is provided
|
|
235
|
-
- **Compatibility**: Any agent that supports AG-UI works. See https://docs.ag-ui.com/
|
|
89
|
+
The `agent` is an AG-UI `AbstractAgent`. Refer to your AG-UI agent implementation for available methods and message formats.
|
|
236
90
|
|
|
237
|
-
|
|
91
|
+
## Core configuration
|
|
238
92
|
|
|
239
|
-
|
|
93
|
+
### `CopilotKitConfig`
|
|
240
94
|
|
|
241
|
-
|
|
95
|
+
`provideCopilotKit` accepts a `CopilotKitConfig` object:
|
|
242
96
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
const runtime = new CopilotRuntime({
|
|
257
|
-
agents: { default: new AnyAGUIAgent() },
|
|
258
|
-
});
|
|
97
|
+
```ts
|
|
98
|
+
export interface CopilotKitConfig {
|
|
99
|
+
runtimeUrl?: string;
|
|
100
|
+
headers?: Record<string, string>;
|
|
101
|
+
licenseKey?: string;
|
|
102
|
+
properties?: Record<string, unknown>;
|
|
103
|
+
agents?: Record<string, AbstractAgent>;
|
|
104
|
+
tools?: ClientTool[];
|
|
105
|
+
renderToolCalls?: RenderToolCallConfig[];
|
|
106
|
+
frontendTools?: FrontendToolConfig[];
|
|
107
|
+
humanInTheLoop?: HumanInTheLoopConfig[];
|
|
108
|
+
}
|
|
109
|
+
```
|
|
259
110
|
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
allowHeaders: ["Content-Type", "Authorization", "X-Requested-With"],
|
|
270
|
-
exposeHeaders: ["Content-Type"],
|
|
271
|
-
credentials: true,
|
|
272
|
-
maxAge: 86400,
|
|
273
|
-
}),
|
|
274
|
-
);
|
|
275
|
-
|
|
276
|
-
// Create the CopilotKit endpoint
|
|
277
|
-
const copilotApp = createCopilotEndpoint({
|
|
278
|
-
runtime,
|
|
279
|
-
basePath: "/api/copilotkit",
|
|
280
|
-
});
|
|
111
|
+
- `runtimeUrl`: URL to your CopilotKit runtime.
|
|
112
|
+
- `headers`: Default headers sent to the runtime.
|
|
113
|
+
- `licenseKey`: Copilot Cloud public API key (`ck_pub_...`), required by `provideCopilotKit`.
|
|
114
|
+
- `properties`: Arbitrary props forwarded to agent runs.
|
|
115
|
+
- `agents`: Local, in-browser agents keyed by `agentId`.
|
|
116
|
+
- `tools`: Tool definitions advertised to the runtime (no handler).
|
|
117
|
+
- `renderToolCalls`: Components to render tool calls in the UI.
|
|
118
|
+
- `frontendTools`: Client-side tools with handlers.
|
|
119
|
+
- `humanInTheLoop`: Tools that pause for user input.
|
|
281
120
|
|
|
282
|
-
|
|
283
|
-
app.route("/", copilotApp);
|
|
121
|
+
### Injection helpers
|
|
284
122
|
|
|
285
|
-
|
|
286
|
-
serve({ fetch: app.fetch, port });
|
|
287
|
-
console.log(
|
|
288
|
-
`CopilotKit runtime listening at http://localhost:${port}/api/copilotkit`,
|
|
289
|
-
);
|
|
290
|
-
```
|
|
123
|
+
- `provideCopilotKit(config)`: Provider for `CopilotKitConfig`.
|
|
291
124
|
|
|
292
|
-
## CopilotKit
|
|
125
|
+
## `CopilotKit` service
|
|
293
126
|
|
|
294
|
-
###
|
|
127
|
+
### Readonly signals
|
|
295
128
|
|
|
296
|
-
-
|
|
297
|
-
|
|
129
|
+
- `agents`: `Signal<Record<string, AbstractAgent>>`
|
|
130
|
+
- `runtimeConnectionStatus`: `Signal<CopilotKitCoreRuntimeConnectionStatus>`
|
|
131
|
+
- `runtimeUrl`: `Signal<string | undefined>`
|
|
132
|
+
- `runtimeTransport`: `Signal<CopilotRuntimeTransport>` (`"rest" | "single"`)
|
|
133
|
+
- `headers`: `Signal<Record<string, string>>`
|
|
134
|
+
- `toolCallRenderConfigs`: `Signal<RenderToolCallConfig[]>`
|
|
135
|
+
- `clientToolCallRenderConfigs`: `Signal<FrontendToolConfig[]>`
|
|
136
|
+
- `humanInTheLoopToolRenderConfigs`: `Signal<HumanInTheLoopConfig[]>`
|
|
298
137
|
|
|
299
|
-
###
|
|
138
|
+
### Methods
|
|
300
139
|
|
|
301
|
-
-
|
|
302
|
-
-
|
|
140
|
+
- `getAgent(agentId: string): AbstractAgent | undefined`
|
|
141
|
+
- `addFrontendTool(config: FrontendToolConfig & { injector: Injector }): void`
|
|
142
|
+
- `addRenderToolCall(config: RenderToolCallConfig): void`
|
|
143
|
+
- `addHumanInTheLoop(config: HumanInTheLoopConfig): void`
|
|
144
|
+
- `removeTool(toolName: string, agentId?: string): void`
|
|
145
|
+
- `updateRuntime(options: { runtimeUrl?: string; runtimeTransport?: CopilotRuntimeTransport; headers?: Record<string,string>; properties?: Record<string, unknown>; agents?: Record<string, AbstractAgent>; }): void`
|
|
303
146
|
|
|
304
|
-
###
|
|
147
|
+
### Advanced
|
|
305
148
|
|
|
306
|
-
-
|
|
307
|
-
- **`provideCopilotChatConfiguration(...)`**: Set UI labels and behavior for chat input/view
|
|
149
|
+
- `core`: The underlying `CopilotKitCore` instance.
|
|
308
150
|
|
|
309
|
-
##
|
|
151
|
+
## Agents
|
|
310
152
|
|
|
311
|
-
|
|
153
|
+
### `injectAgentStore`
|
|
312
154
|
|
|
313
|
-
|
|
155
|
+
```ts
|
|
156
|
+
const store = injectAgentStore("default");
|
|
157
|
+
// or: injectAgentStore(signal(agentId))
|
|
158
|
+
```
|
|
314
159
|
|
|
315
|
-
|
|
160
|
+
Returns a `Signal<AgentStore>`. The store exposes:
|
|
316
161
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
162
|
+
- `agent`: `AbstractAgent`
|
|
163
|
+
- `messages`: `Signal<Message[]>`
|
|
164
|
+
- `state`: `Signal<any>`
|
|
165
|
+
- `isRunning`: `Signal<boolean>`
|
|
166
|
+
- `teardown()`: Clean up subscriptions
|
|
320
167
|
|
|
321
|
-
|
|
322
|
-
selector: "my-custom-chat",
|
|
323
|
-
template: `
|
|
324
|
-
<div class="custom-chat">
|
|
325
|
-
<div *ngFor="let msg of messages()" class="message">
|
|
326
|
-
{{ msg.content }}
|
|
327
|
-
</div>
|
|
328
|
-
<input [disabled]="isRunning()" (keyup.enter)="sendMessage($event)" />
|
|
329
|
-
</div>
|
|
330
|
-
`,
|
|
331
|
-
})
|
|
332
|
-
export class MyCustomChatComponent {
|
|
333
|
-
protected agent!: ReturnType<typeof watchAgent>["agent"];
|
|
334
|
-
protected messages!: ReturnType<typeof watchAgent>["messages"];
|
|
335
|
-
protected isRunning!: ReturnType<typeof watchAgent>["isRunning"];
|
|
336
|
-
|
|
337
|
-
constructor() {
|
|
338
|
-
const w = watchAgent({ agentId: "custom" });
|
|
339
|
-
this.agent = w.agent;
|
|
340
|
-
this.messages = w.messages;
|
|
341
|
-
this.isRunning = w.isRunning;
|
|
342
|
-
|
|
343
|
-
// React to agent changes
|
|
344
|
-
effect(() => {
|
|
345
|
-
const currentAgent = this.agent();
|
|
346
|
-
if (currentAgent) {
|
|
347
|
-
console.log("Agent ready:", currentAgent.id);
|
|
348
|
-
}
|
|
349
|
-
});
|
|
350
|
-
}
|
|
168
|
+
If the agent is not available locally but a `runtimeUrl` is configured, a proxy agent is created while the runtime connects. If the agent still cannot be resolved, an error is thrown that includes the configured runtime and known agent IDs.
|
|
351
169
|
|
|
352
|
-
|
|
353
|
-
const input = event.target as HTMLInputElement;
|
|
354
|
-
const content = input.value.trim();
|
|
355
|
-
if (!content || !this.agent()) return;
|
|
170
|
+
### `CopilotkitAgentFactory`
|
|
356
171
|
|
|
357
|
-
|
|
358
|
-
this.agent()!.addMessage({ role: "user", content });
|
|
359
|
-
input.value = "";
|
|
360
|
-
await this.agent()!.runAgent();
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
```
|
|
172
|
+
Advanced factory for creating `AgentStore` signals. Most apps should use `injectAgentStore` instead.
|
|
364
173
|
|
|
365
|
-
|
|
174
|
+
## Agent context
|
|
366
175
|
|
|
367
|
-
|
|
176
|
+
### `connectAgentContext`
|
|
368
177
|
|
|
369
|
-
|
|
370
|
-
import { Component, Injector } from "@angular/core";
|
|
371
|
-
import { watchAgent, watchAgentWith } from "@copilotkitnext/angular";
|
|
178
|
+
Connect AG-UI context to the runtime (auto-cleanup when the effect is destroyed):
|
|
372
179
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
template: `
|
|
376
|
-
<button (click)="switchToAgent('sales')">Sales Agent</button>
|
|
377
|
-
<button (click)="switchToAgent('support')">Support Agent</button>
|
|
378
|
-
<div>Current Agent: {{ agent()?.id || "None" }}</div>
|
|
379
|
-
`,
|
|
380
|
-
})
|
|
381
|
-
export class AgentSwitcherComponent {
|
|
382
|
-
protected agent!: ReturnType<typeof watchAgent>["agent"];
|
|
383
|
-
protected messages!: ReturnType<typeof watchAgent>["messages"];
|
|
384
|
-
protected isRunning!: ReturnType<typeof watchAgent>["isRunning"];
|
|
385
|
-
private watcher?: ReturnType<typeof watchAgent>;
|
|
386
|
-
|
|
387
|
-
constructor(private injector: Injector) {
|
|
388
|
-
// Initialize with default agent
|
|
389
|
-
this.switchToAgent("default");
|
|
390
|
-
}
|
|
180
|
+
```ts
|
|
181
|
+
import { connectAgentContext } from "@copilotkitnext/angular";
|
|
391
182
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
183
|
+
connectAgentContext({
|
|
184
|
+
description: "User preferences",
|
|
185
|
+
value: { theme: "dark" },
|
|
186
|
+
});
|
|
187
|
+
```
|
|
395
188
|
|
|
396
|
-
|
|
397
|
-
const w = watchAgentWith(this.injector, { agentId });
|
|
189
|
+
You must call it within an injection context (e.g., inside a component constructor or `runInInjectionContext`), or pass an explicit `Injector`:
|
|
398
190
|
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
this.messages = w.messages;
|
|
402
|
-
this.isRunning = w.isRunning;
|
|
403
|
-
this.watcher = w;
|
|
404
|
-
}
|
|
405
|
-
}
|
|
191
|
+
```ts
|
|
192
|
+
connectAgentContext(contextSignal, { injector });
|
|
406
193
|
```
|
|
407
194
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
To render tool calls in a headless UI, register renderers in your providers and drop the lightweight view in your template.
|
|
195
|
+
## Tools and tool rendering
|
|
411
196
|
|
|
412
|
-
|
|
197
|
+
### Types
|
|
413
198
|
|
|
414
199
|
```ts
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
200
|
+
export interface RenderToolCallConfig<Args> {
|
|
201
|
+
name: string; // tool name, or "*" for wildcard
|
|
202
|
+
args: z.ZodType<Args>; // Zod schema for args
|
|
203
|
+
component: Type<ToolRenderer<Args>>;
|
|
204
|
+
agentId?: string; // optional agent scope
|
|
205
|
+
}
|
|
418
206
|
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
<div style="font-weight:600;margin-bottom:6px;">Tool: {{ name }}</div>
|
|
427
|
-
<pre style="margin:0;white-space:pre-wrap;">{{ args | json }}</pre>
|
|
428
|
-
<div *ngIf="result" style="margin-top:6px;">Result: {{ result }}</div>
|
|
429
|
-
</div>
|
|
430
|
-
`,
|
|
431
|
-
})
|
|
432
|
-
export class WildcardToolRenderComponent {
|
|
433
|
-
@Input() name!: string;
|
|
434
|
-
@Input() args: any;
|
|
435
|
-
@Input() status: any;
|
|
436
|
-
@Input() result?: string;
|
|
207
|
+
export interface FrontendToolConfig<Args> {
|
|
208
|
+
name: string;
|
|
209
|
+
description: string;
|
|
210
|
+
parameters: z.ZodType<Args>;
|
|
211
|
+
component?: Type<ToolRenderer<Args>>; // optional UI renderer
|
|
212
|
+
handler: (args: Args, context: FrontendToolHandlerContext) => Promise<unknown>;
|
|
213
|
+
agentId?: string;
|
|
437
214
|
}
|
|
438
215
|
|
|
439
|
-
export
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
216
|
+
export interface HumanInTheLoopConfig<Args> {
|
|
217
|
+
name: string;
|
|
218
|
+
description: string;
|
|
219
|
+
parameters: z.ZodType<Args>;
|
|
220
|
+
component: Type<HumanInTheLoopToolRenderer<Args>>;
|
|
221
|
+
agentId?: string;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export type ClientTool<Args> = Omit<FrontendTool<Args>, \"handler\"> & {
|
|
225
|
+
renderer?: Type<ToolRenderer<Args>>;
|
|
446
226
|
};
|
|
447
227
|
```
|
|
448
228
|
|
|
449
|
-
|
|
229
|
+
Renderer components receive a signal:
|
|
450
230
|
|
|
451
231
|
```ts
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
CopilotChatToolCallsViewComponent,
|
|
456
|
-
} from "@copilotkitnext/angular";
|
|
232
|
+
export interface ToolRenderer<Args> {
|
|
233
|
+
toolCall: Signal<AngularToolCall<Args>>;
|
|
234
|
+
}
|
|
457
235
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
imports: [CopilotChatToolCallsViewComponent],
|
|
461
|
-
template: `
|
|
462
|
-
<div *ngFor="let m of messages()">
|
|
463
|
-
<div>{{ m.role }}: {{ m.content }}</div>
|
|
464
|
-
<ng-container *ngIf="m.role === 'assistant'">
|
|
465
|
-
<copilot-chat-tool-calls-view
|
|
466
|
-
[message]="m"
|
|
467
|
-
[messages]="messages()"
|
|
468
|
-
[isLoading]="isRunning()"
|
|
469
|
-
/>
|
|
470
|
-
</ng-container>
|
|
471
|
-
</div>
|
|
472
|
-
`,
|
|
473
|
-
})
|
|
474
|
-
export class HeadlessWithToolsComponent {
|
|
475
|
-
agent = watchAgent().agent;
|
|
476
|
-
messages = watchAgent().messages;
|
|
477
|
-
isRunning = watchAgent().isRunning;
|
|
236
|
+
export interface HumanInTheLoopToolRenderer<Args> {
|
|
237
|
+
toolCall: Signal<HumanInTheLoopToolCall<Args>>; // includes respond(result)
|
|
478
238
|
}
|
|
479
239
|
```
|
|
480
240
|
|
|
481
|
-
|
|
241
|
+
`AngularToolCall` / `HumanInTheLoopToolCall` expose `args`, `status` (`"in-progress" | "executing" | "complete"`), and `result`.
|
|
482
242
|
|
|
483
|
-
|
|
484
|
-
- You can also register tool renders declaratively via the `CopilotKitFrontendToolDirective` by using `[copilotkitFrontendTool]` in templates.
|
|
243
|
+
### Register tools with DI
|
|
485
244
|
|
|
486
|
-
|
|
245
|
+
These helpers auto-remove tools when the current injection context is destroyed:
|
|
246
|
+
Call them from an injection context (e.g., a component constructor, directive, or `runInInjectionContext`).
|
|
247
|
+
|
|
248
|
+
```ts
|
|
249
|
+
import {
|
|
250
|
+
registerFrontendTool,
|
|
251
|
+
registerRenderToolCall,
|
|
252
|
+
registerHumanInTheLoop,
|
|
253
|
+
} from "@copilotkitnext/angular";
|
|
254
|
+
import { z } from "zod";
|
|
487
255
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
256
|
+
registerFrontendTool({
|
|
257
|
+
name: "lookup",
|
|
258
|
+
description: "Fetch a record",
|
|
259
|
+
parameters: z.object({ id: z.string() }),
|
|
260
|
+
handler: async ({ id }) => ({ id, ok: true }),
|
|
261
|
+
});
|
|
493
262
|
|
|
494
|
-
|
|
263
|
+
registerRenderToolCall({
|
|
264
|
+
name: "*", // wildcard renderer
|
|
265
|
+
args: z.any(),
|
|
266
|
+
component: MyToolCallRenderer,
|
|
267
|
+
});
|
|
495
268
|
|
|
496
|
-
|
|
269
|
+
registerHumanInTheLoop({
|
|
270
|
+
name: "approval",
|
|
271
|
+
description: "Request approval",
|
|
272
|
+
parameters: z.object({ reason: z.string() }),
|
|
273
|
+
component: ApprovalRenderer,
|
|
274
|
+
});
|
|
275
|
+
```
|
|
497
276
|
|
|
498
|
-
|
|
499
|
-
2. **Start both demo server and Angular demo app**: pnpm build && pnpm demo:angular`
|
|
500
|
-
- Frontend: runs on http://localhost:4200
|
|
501
|
-
- Backend: runs on http://localhost:3001/api/copilotkit
|
|
502
|
-
3. **Prerequisite**: Set `OPENAI_API_KEY` in `apps/angular/demo-server/.env` if using the OpenAI demo agent
|
|
277
|
+
### Configure tools in `provideCopilotKit`
|
|
503
278
|
|
|
504
|
-
|
|
279
|
+
```ts
|
|
280
|
+
provideCopilotKit({
|
|
281
|
+
licenseKey: "ck_pub_your_public_api_key",
|
|
282
|
+
frontendTools: [
|
|
283
|
+
/* FrontendToolConfig[] */
|
|
284
|
+
],
|
|
285
|
+
renderToolCalls: [
|
|
286
|
+
/* RenderToolCallConfig[] */
|
|
287
|
+
],
|
|
288
|
+
humanInTheLoop: [
|
|
289
|
+
/* HumanInTheLoopConfig[] */
|
|
290
|
+
],
|
|
291
|
+
tools: [
|
|
292
|
+
/* ClientTool[] */
|
|
293
|
+
],
|
|
294
|
+
});
|
|
295
|
+
```
|
|
505
296
|
|
|
506
|
-
|
|
507
|
-
- **Clean**: `pnpm clean`
|
|
508
|
-
- **Package-only dev (watch)**: `pnpm dev`
|
|
297
|
+
`tools` are advertised to the runtime. If you include `renderer` + `parameters` on a `ClientTool`, CopilotKit will also register a renderer for tool calls.
|
|
509
298
|
|
|
510
|
-
##
|
|
299
|
+
## `RenderToolCalls` component
|
|
511
300
|
|
|
512
|
-
|
|
301
|
+
`RenderToolCalls` renders tool call components under an assistant message based on registered render configs.
|
|
513
302
|
|
|
514
|
-
```
|
|
515
|
-
|
|
303
|
+
```html
|
|
304
|
+
<copilot-render-tool-calls
|
|
305
|
+
[message]="assistantMessage"
|
|
306
|
+
[messages]="messages"
|
|
307
|
+
[isLoading]="isRunning"
|
|
308
|
+
></copilot-render-tool-calls>
|
|
516
309
|
```
|
|
517
310
|
|
|
518
|
-
|
|
519
|
-
- For live chat stories, ensure the demo server is running so the chat can connect:
|
|
520
|
-
```bash
|
|
521
|
-
pnpm --filter @copilotkitnext/angular-demo-server dev
|
|
522
|
-
```
|
|
311
|
+
Inputs:
|
|
523
312
|
|
|
524
|
-
|
|
313
|
+
- `message`: `AssistantMessage` (must include `toolCalls`)
|
|
314
|
+
- `messages`: full `Message[]` list (used to find tool results)
|
|
315
|
+
- `isLoading`: whether the agent is currently running
|
|
525
316
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
317
|
+
Tool arguments are parsed with `partialJSONParse`, so incomplete JSON during streaming still renders.
|
|
318
|
+
|
|
319
|
+
## Runtime notes
|
|
320
|
+
|
|
321
|
+
- Set `runtimeUrl` to your CopilotKit runtime endpoint.
|
|
322
|
+
- If you need to change runtime settings at runtime, call `CopilotKit.updateRuntime(...)`.
|
|
323
|
+
- `runtimeTransport` supports `"rest"` or `"single"` (SSE single-stream transport).
|
|
529
324
|
|
|
530
|
-
##
|
|
325
|
+
## Not documented here
|
|
531
326
|
|
|
532
|
-
|
|
533
|
-
- If using custom CORS or non-default ports, update `runtimeUrl` and server CORS settings accordingly
|
|
534
|
-
- Styles must be included for proper rendering; if customizing CSS, prefer overriding classes instead of modifying the distributed CSS
|
|
327
|
+
This package also exports a full set of chat UI components under `src/lib/components/chat`. Those APIs are intentionally omitted from this README.
|