@copilotkit/vue 2.0.0-rc.26 → 2.0.0-rc.28
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/CONTRIBUTOR_GUIDE.md +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{use-render-activity-message-BVZr0Z-G.js → use-render-activity-message-BLHkxK7Q.js} +5686 -5983
- package/dist/use-render-activity-message-BLHkxK7Q.js.map +1 -0
- package/dist/use-render-activity-message-d1Uz5YiB.cjs +113 -0
- package/dist/use-render-activity-message-d1Uz5YiB.cjs.map +1 -0
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts +3 -6
- package/dist/v2/components/a2ui/A2UIBuiltInToolCallRenderer.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatFeedbackCommentPopover.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +1 -16
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatReasoningMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotThreadsDrawer.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/message-feedback.d.ts +20 -0
- package/dist/v2/components/chat/message-feedback.d.ts.map +1 -1
- package/dist/v2/hooks/use-configure-suggestions.d.ts.map +1 -1
- package/dist/v2/hooks/use-default-render-tool.d.ts +2 -7
- package/dist/v2/hooks/use-default-render-tool.d.ts.map +1 -1
- package/dist/v2/hooks/use-frontend-tool.d.ts +2 -2
- package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
- package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
- package/dist/v2/hooks/use-suggestions.d.ts.map +1 -1
- package/dist/v2/hooks/use-threads.d.ts +6 -15
- package/dist/v2/hooks/use-threads.d.ts.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/lib/vue-core.d.ts +16 -2
- package/dist/v2/lib/vue-core.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/__tests__/build-entries.test.ts +3 -1
- package/src/v2/components/a2ui/A2UIBuiltInToolCallRenderer.ts +4 -19
- package/src/v2/components/chat/CopilotChat.vue +50 -218
- package/src/v2/components/chat/CopilotChatAssistantMessage.vue +28 -141
- package/src/v2/components/chat/CopilotChatFeedbackCommentPopover.vue +11 -76
- package/src/v2/components/chat/CopilotChatInput.vue +82 -269
- package/src/v2/components/chat/CopilotChatMessageView.vue +14 -64
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +25 -52
- package/src/v2/components/chat/CopilotChatView.vue +92 -135
- package/src/v2/components/chat/CopilotPopupViewInternal.vue +18 -58
- package/src/v2/components/chat/CopilotSidebarViewInternal.vue +22 -45
- package/src/v2/components/chat/CopilotThreadsDrawer.vue +6 -3
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +43 -0
- package/src/v2/components/chat/__tests__/CopilotChatView.pinToSend.test.ts +43 -1
- package/src/v2/components/chat/message-feedback.ts +33 -1
- package/src/v2/hooks/use-configure-suggestions.ts +3 -4
- package/src/v2/hooks/use-default-render-tool.ts +7 -68
- package/src/v2/hooks/use-frontend-tool.ts +10 -20
- package/src/v2/hooks/use-render-activity-message.ts +4 -2
- package/src/v2/hooks/use-suggestions.ts +9 -4
- package/src/v2/hooks/use-threads.ts +6 -15
- package/src/v2/lib/vue-core.ts +19 -2
- package/src/v2/providers/CopilotKitProvider.vue +107 -184
- package/src/v2/providers/__tests__/CopilotKitProvider.a2ui.test.ts +18 -0
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +35 -2
- package/dist/use-render-activity-message-8p2HwK2y.cjs +0 -114
- package/dist/use-render-activity-message-8p2HwK2y.cjs.map +0 -1
- package/dist/use-render-activity-message-BVZr0Z-G.js.map +0 -1
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { ɵanySchema } from "@copilotkit/shared";
|
|
3
2
|
import {
|
|
4
3
|
computed,
|
|
5
4
|
h,
|
|
@@ -16,25 +15,30 @@ import type { Component, FunctionalComponent } from "vue";
|
|
|
16
15
|
import type { Catalog, ComponentApi } from "@a2ui/web_core/v0_9";
|
|
17
16
|
import {
|
|
18
17
|
ɵLearningAutoStarter,
|
|
19
|
-
|
|
18
|
+
ɵassembleActivityRenderers,
|
|
19
|
+
ɵassembleHumanInTheLoop,
|
|
20
|
+
ɵassembleProviderToolRenderers,
|
|
21
|
+
ɵassembleProviderTools,
|
|
20
22
|
ɵhitlRenderProps,
|
|
23
|
+
ɵresolveA2UIActivation,
|
|
24
|
+
ɵstableArrayPropWarning,
|
|
21
25
|
ɵtoLearningConfig,
|
|
22
26
|
} from "@copilotkit/core";
|
|
23
27
|
import type {
|
|
24
28
|
CopilotKitHeadersSource,
|
|
25
29
|
FrontendTool,
|
|
30
|
+
ɵHumanInTheLoopRegistry,
|
|
26
31
|
ɵRuntimeInfo,
|
|
32
|
+
ɵStableArrayProp,
|
|
27
33
|
} from "@copilotkit/core";
|
|
28
34
|
import {
|
|
29
|
-
|
|
30
|
-
ɵbuildOpenGenerativeUIContexts,
|
|
35
|
+
ɵaddOpenGenerativeUIContexts,
|
|
31
36
|
ɵcreateOpenGenerativeUITool,
|
|
32
37
|
ɵisOpenGenerativeUIActive,
|
|
33
38
|
ɵpublicKeyHeaderDefaults,
|
|
34
39
|
ɵreportProviderConfigDiagnostics,
|
|
35
40
|
ɵresolveLicenseState,
|
|
36
41
|
ɵresolveProviderConfig,
|
|
37
|
-
ɵtoolRendererShapeChanged,
|
|
38
42
|
ɵwithHeaderDefaults,
|
|
39
43
|
} from "@copilotkit/core";
|
|
40
44
|
import { shouldEnableInspector } from "@copilotkit/shared";
|
|
@@ -136,74 +140,36 @@ provide(InspectorKey, {
|
|
|
136
140
|
openInspector,
|
|
137
141
|
});
|
|
138
142
|
|
|
139
|
-
const initialRenderToolCalls = props.renderToolCalls ?? [];
|
|
140
|
-
const initialFrontendTools = props.frontendTools;
|
|
141
|
-
const initialHumanInTheLoop = props.humanInTheLoop;
|
|
142
|
-
const initialRenderCustomMessages = props.renderCustomMessages;
|
|
143
|
-
const initialRenderActivityMessages = props.renderActivityMessages;
|
|
144
|
-
const initialSandboxFunctions = props.openGenerativeUI?.sandboxFunctions;
|
|
145
|
-
|
|
146
143
|
// Props that come from reactive state arrive as deep proxies. Zod 4 schemas
|
|
147
144
|
// break behind a Vue proxy (their `_zod` property is read-only and
|
|
148
145
|
// non-configurable), so read tools and renderers through their raw objects.
|
|
149
146
|
const rawEntries = <T>(entries: readonly T[] | undefined): T[] =>
|
|
150
147
|
[...toRaw(entries ?? [])].map((entry) => toRaw(entry));
|
|
151
148
|
|
|
152
|
-
//
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
(
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
console.error(ɵSTABLE_ARRAY_WARNINGS.humanInTheLoop);
|
|
177
|
-
}
|
|
178
|
-
},
|
|
179
|
-
);
|
|
180
|
-
|
|
181
|
-
watch(
|
|
182
|
-
() => props.renderCustomMessages,
|
|
183
|
-
(next) => {
|
|
184
|
-
if (next !== initialRenderCustomMessages) {
|
|
185
|
-
console.error(ɵSTABLE_ARRAY_WARNINGS.renderCustomMessages);
|
|
186
|
-
}
|
|
187
|
-
},
|
|
188
|
-
);
|
|
189
|
-
|
|
190
|
-
watch(
|
|
191
|
-
() => props.renderActivityMessages,
|
|
192
|
-
(next) => {
|
|
193
|
-
if (next !== initialRenderActivityMessages) {
|
|
194
|
-
console.error(ɵSTABLE_ARRAY_WARNINGS.renderActivityMessages);
|
|
195
|
-
}
|
|
196
|
-
},
|
|
197
|
-
);
|
|
198
|
-
|
|
199
|
-
watch(
|
|
200
|
-
() => props.openGenerativeUI?.sandboxFunctions,
|
|
201
|
-
(next) => {
|
|
202
|
-
if (next !== initialSandboxFunctions) {
|
|
203
|
-
console.error(ɵSTABLE_ARRAY_WARNINGS.sandboxFunctions);
|
|
204
|
-
}
|
|
205
|
-
},
|
|
206
|
-
);
|
|
149
|
+
// Array props must keep their identity; core decides when a change warns
|
|
150
|
+
// (for `renderToolCalls`, only a change of the agentId:name pairs).
|
|
151
|
+
const stableArrayProps: Record<
|
|
152
|
+
ɵStableArrayProp,
|
|
153
|
+
() => readonly unknown[] | undefined
|
|
154
|
+
> = {
|
|
155
|
+
renderToolCalls: () => props.renderToolCalls,
|
|
156
|
+
frontendTools: () => props.frontendTools,
|
|
157
|
+
humanInTheLoop: () => props.humanInTheLoop,
|
|
158
|
+
renderCustomMessages: () => props.renderCustomMessages,
|
|
159
|
+
renderActivityMessages: () => props.renderActivityMessages,
|
|
160
|
+
sandboxFunctions: () => props.openGenerativeUI?.sandboxFunctions,
|
|
161
|
+
};
|
|
162
|
+
for (const [name, read] of Object.entries(stableArrayProps)) {
|
|
163
|
+
const initial = read();
|
|
164
|
+
watch(read, (next) => {
|
|
165
|
+
const warning = ɵstableArrayPropWarning(
|
|
166
|
+
name as ɵStableArrayProp,
|
|
167
|
+
initial,
|
|
168
|
+
next,
|
|
169
|
+
);
|
|
170
|
+
if (warning) console.error(warning);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
207
173
|
|
|
208
174
|
// Key fallback, Copilot Cloud URL, transport, agent merge and the catalog
|
|
209
175
|
// property all come from core.
|
|
@@ -270,71 +236,42 @@ watch(
|
|
|
270
236
|
{ immediate: true },
|
|
271
237
|
);
|
|
272
238
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
) =>
|
|
239
|
+
type FrontendToolRender = NonNullable<VueFrontendTool["render"]>;
|
|
240
|
+
|
|
241
|
+
// The tools and tool-call renderers for core (assembly rules from core).
|
|
242
|
+
// Human-in-the-loop renders are wrapped once per `humanInTheLoop` change: a
|
|
243
|
+
// new wrapper is a new component type, so Vue would remount the card.
|
|
244
|
+
const humanInTheLoopAssembly = computed(() =>
|
|
245
|
+
ɵassembleHumanInTheLoop<FrontendToolRender, unknown>({
|
|
246
|
+
humanInTheLoop: rawEntries(props.humanInTheLoop),
|
|
247
|
+
// Core parks each call by tool call id until the render responds. The core
|
|
248
|
+
// is created further down, so read its registry lazily.
|
|
249
|
+
humanInTheLoopRegistry: (): ɵHumanInTheLoopRegistry =>
|
|
250
|
+
copilotkit.value.ɵhumanInTheLoop,
|
|
251
|
+
wrapHumanInTheLoopRender: (ToolComponent, tool, registry) =>
|
|
252
|
+
((renderProps: VueToolCallRendererRenderProps<unknown>) =>
|
|
287
253
|
h(
|
|
288
254
|
ToolComponent as Parameters<typeof h>[0],
|
|
289
255
|
ɵhitlRenderProps(renderProps, tool, registry()),
|
|
290
|
-
)
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
tools.push(t as FrontendTool);
|
|
310
|
-
}
|
|
311
|
-
tools.push(...processedHumanInTheLoop.value.tools);
|
|
312
|
-
return tools;
|
|
313
|
-
});
|
|
314
|
-
|
|
315
|
-
const allRenderToolCalls = computed(() => {
|
|
316
|
-
const combined: VueToolCallRenderer<unknown>[] = [
|
|
317
|
-
...rawEntries(props.renderToolCalls),
|
|
318
|
-
];
|
|
319
|
-
for (const tool of [
|
|
320
|
-
...rawEntries(props.frontendTools),
|
|
321
|
-
...builtInFrontendTools.value,
|
|
322
|
-
]) {
|
|
323
|
-
if (tool.render) {
|
|
324
|
-
const args =
|
|
325
|
-
tool.parameters ?? (tool.name === "*" ? ɵanySchema : undefined);
|
|
326
|
-
if (args) {
|
|
327
|
-
combined.push({
|
|
328
|
-
name: tool.name,
|
|
329
|
-
args,
|
|
330
|
-
render: tool.render,
|
|
331
|
-
} as VueToolCallRenderer<unknown>);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
combined.push(...processedHumanInTheLoop.value.renderToolCalls);
|
|
336
|
-
return combined;
|
|
337
|
-
});
|
|
256
|
+
)) as FrontendToolRender,
|
|
257
|
+
}),
|
|
258
|
+
);
|
|
259
|
+
const allTools = computed<FrontendTool[]>(() =>
|
|
260
|
+
ɵassembleProviderTools({
|
|
261
|
+
frontendTools: rawEntries(props.frontendTools),
|
|
262
|
+
builtInFrontendTools: builtInFrontendTools.value,
|
|
263
|
+
humanInTheLoop: humanInTheLoopAssembly.value,
|
|
264
|
+
}),
|
|
265
|
+
);
|
|
266
|
+
const allRenderToolCalls = computed(
|
|
267
|
+
() =>
|
|
268
|
+
ɵassembleProviderToolRenderers({
|
|
269
|
+
renderToolCalls: rawEntries(props.renderToolCalls),
|
|
270
|
+
frontendTools: rawEntries(props.frontendTools),
|
|
271
|
+
builtInFrontendTools: builtInFrontendTools.value,
|
|
272
|
+
humanInTheLoop: humanInTheLoopAssembly.value,
|
|
273
|
+
}) as VueToolCallRenderer<unknown>[],
|
|
274
|
+
);
|
|
338
275
|
|
|
339
276
|
const allRenderCustomMessages = computed(
|
|
340
277
|
() => props.renderCustomMessages ?? [],
|
|
@@ -363,9 +300,12 @@ const openGenerativeUIActive = computed(() =>
|
|
|
363
300
|
// A catalog passed to the provider is enough to turn A2UI on: render the
|
|
364
301
|
// surfaces locally and forward the catalog signal so the runtime injects the
|
|
365
302
|
// render tool — no runtime-side `a2ui` config required.
|
|
366
|
-
const a2uiCatalogProvided = computed(() => !!props.a2ui?.catalog);
|
|
367
303
|
const a2uiActive = computed(
|
|
368
|
-
() =>
|
|
304
|
+
() =>
|
|
305
|
+
ɵresolveA2UIActivation({
|
|
306
|
+
runtimeEnabled: runtimeA2UIEnabled.value,
|
|
307
|
+
hasCatalog: !!props.a2ui?.catalog,
|
|
308
|
+
}).active,
|
|
369
309
|
);
|
|
370
310
|
// The catalog with components disabled in the Inspector removed; set by
|
|
371
311
|
// `registerA2UICatalog` below once the core exists.
|
|
@@ -390,47 +330,36 @@ const builtInFrontendTools = computed<VueFrontendTool[]>(() => {
|
|
|
390
330
|
];
|
|
391
331
|
});
|
|
392
332
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
}),
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return renderers;
|
|
428
|
-
});
|
|
429
|
-
|
|
430
|
-
const allRenderActivityMessages = computed(() => [
|
|
431
|
-
...rawEntries(props.renderActivityMessages),
|
|
432
|
-
...builtInActivityRenderers.value,
|
|
433
|
-
]);
|
|
333
|
+
// The app's activity renderers, then the built-in ones (order from core).
|
|
334
|
+
const allRenderActivityMessages = computed(() =>
|
|
335
|
+
ɵassembleActivityRenderers<VueActivityMessageRenderer<unknown>>({
|
|
336
|
+
app: rawEntries(props.renderActivityMessages),
|
|
337
|
+
a2ui: a2uiActive.value
|
|
338
|
+
? createA2UIMessageRenderer({
|
|
339
|
+
theme: props.a2ui?.theme ?? {},
|
|
340
|
+
catalog: a2uiFilteredCatalog.value ?? props.a2ui?.catalog,
|
|
341
|
+
loadingComponent: props.a2ui?.loadingComponent,
|
|
342
|
+
recovery: props.a2ui?.recovery,
|
|
343
|
+
onAction: props.a2ui?.onAction,
|
|
344
|
+
})
|
|
345
|
+
: undefined,
|
|
346
|
+
builtIns: [
|
|
347
|
+
{
|
|
348
|
+
activityType: MCPAppsActivityType,
|
|
349
|
+
content: MCPAppsActivityContentSchema,
|
|
350
|
+
render: (props.mcpApps?.allowSameOriginFallback
|
|
351
|
+
? SameOriginMCPAppsActivityRenderer
|
|
352
|
+
: MCPAppsActivityRenderer) as unknown as VueActivityMessageRenderer<unknown>["render"],
|
|
353
|
+
},
|
|
354
|
+
openGenerativeUIActive.value && {
|
|
355
|
+
activityType: OpenGenerativeUIActivityType,
|
|
356
|
+
content: OpenGenerativeUIContentSchema,
|
|
357
|
+
render:
|
|
358
|
+
OpenGenerativeUIActivityRenderer as unknown as VueActivityMessageRenderer<unknown>["render"],
|
|
359
|
+
},
|
|
360
|
+
],
|
|
361
|
+
}),
|
|
362
|
+
);
|
|
434
363
|
|
|
435
364
|
const learningConfig = computed(() => ɵtoLearningConfig(props.learning));
|
|
436
365
|
|
|
@@ -633,7 +562,6 @@ registerA2UICatalog(copilotkit, {
|
|
|
633
562
|
},
|
|
634
563
|
});
|
|
635
564
|
|
|
636
|
-
const providerContextIds = ref<string[]>([]);
|
|
637
565
|
watch(
|
|
638
566
|
[
|
|
639
567
|
openGenerativeUIActive,
|
|
@@ -643,17 +571,12 @@ watch(
|
|
|
643
571
|
([active, functions, designSkill], _previous, onCleanup) => {
|
|
644
572
|
if (!active) return;
|
|
645
573
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
onCleanup(() => {
|
|
653
|
-
for (const id of ids) {
|
|
654
|
-
copilotkit.value.removeContext(id);
|
|
655
|
-
}
|
|
656
|
-
});
|
|
574
|
+
onCleanup(
|
|
575
|
+
ɵaddOpenGenerativeUIContexts(copilotkit.value, {
|
|
576
|
+
designSkill,
|
|
577
|
+
sandboxFunctions: functions,
|
|
578
|
+
}),
|
|
579
|
+
);
|
|
657
580
|
},
|
|
658
581
|
{ immediate: true },
|
|
659
582
|
);
|
|
@@ -70,6 +70,24 @@ describe("CopilotKitProvider a2ui catalog auto-enable", () => {
|
|
|
70
70
|
expect(a2uiRenderer).toBeDefined();
|
|
71
71
|
});
|
|
72
72
|
|
|
73
|
+
it("keeps the built-in render_a2ui renderer and the app's renderers together when the app's renderers change", async () => {
|
|
74
|
+
const catalog = { id: "test", components: new Map() };
|
|
75
|
+
const weather = { name: "weather", args: z.any(), render: () => null };
|
|
76
|
+
const { wrapper, observedCore } = mountProvider({
|
|
77
|
+
a2ui: { catalog },
|
|
78
|
+
renderToolCalls: [weather],
|
|
79
|
+
});
|
|
80
|
+
const names = () =>
|
|
81
|
+
observedCore.value?.renderToolCalls.map((renderer) => renderer.name);
|
|
82
|
+
expect(names()).toEqual(["weather", "render_a2ui"]);
|
|
83
|
+
|
|
84
|
+
await wrapper.setProps({
|
|
85
|
+
renderToolCalls: [weather, { ...weather, name: "search" }],
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
expect(names()).toEqual(["weather", "search", "render_a2ui"]);
|
|
89
|
+
});
|
|
90
|
+
|
|
73
91
|
it("does not register an a2ui-surface renderer when no catalog is provided and runtime has not signaled a2uiEnabled", () => {
|
|
74
92
|
const { observedCore } = mountProvider({ a2ui: { theme: {} } });
|
|
75
93
|
|
|
@@ -322,7 +322,7 @@ describe("CopilotKitProvider", () => {
|
|
|
322
322
|
expect(renderTool?.render).toStrictEqual(TestComponent);
|
|
323
323
|
});
|
|
324
324
|
|
|
325
|
-
it("
|
|
325
|
+
it("scopes frontendTools-derived render entries by agentId, like useFrontendTool", () => {
|
|
326
326
|
const TestComponent = defineComponent({
|
|
327
327
|
setup() {
|
|
328
328
|
return () => h("div", "Test");
|
|
@@ -344,7 +344,7 @@ describe("CopilotKitProvider", () => {
|
|
|
344
344
|
);
|
|
345
345
|
|
|
346
346
|
expect(renderTool).toBeDefined();
|
|
347
|
-
expect(renderTool?.agentId).
|
|
347
|
+
expect(renderTool?.agentId).toBe("specific-agent");
|
|
348
348
|
});
|
|
349
349
|
});
|
|
350
350
|
|
|
@@ -411,6 +411,39 @@ describe("CopilotKitProvider", () => {
|
|
|
411
411
|
expect(typeof renderTool?.render).toBe("function");
|
|
412
412
|
});
|
|
413
413
|
|
|
414
|
+
it("keeps the wrapped render and the tools when only renderToolCalls changes", async () => {
|
|
415
|
+
// A new wrapper is a new component type, so Vue would remount the card
|
|
416
|
+
// and lose its state.
|
|
417
|
+
const humanInTheLoop: VueHumanInTheLoop[] = [
|
|
418
|
+
{
|
|
419
|
+
name: "approvalTool",
|
|
420
|
+
parameters: z.object({}),
|
|
421
|
+
render: HitlComponent,
|
|
422
|
+
},
|
|
423
|
+
];
|
|
424
|
+
const weather = () => [
|
|
425
|
+
{ name: "weather", args: z.any(), render: HitlComponent },
|
|
426
|
+
];
|
|
427
|
+
const { wrapper, getCore } = mountWithProvider(() => h("div"), {
|
|
428
|
+
humanInTheLoop,
|
|
429
|
+
renderToolCalls: weather(),
|
|
430
|
+
});
|
|
431
|
+
const approveRender = () =>
|
|
432
|
+
getCore().renderToolCalls.find((rc) => rc.name === "approvalTool")
|
|
433
|
+
?.render;
|
|
434
|
+
const before = approveRender();
|
|
435
|
+
const setTools = vi.spyOn(getCore(), "setTools");
|
|
436
|
+
|
|
437
|
+
await wrapper.setProps({ renderToolCalls: weather() });
|
|
438
|
+
await flush();
|
|
439
|
+
|
|
440
|
+
expect(getCore().renderToolCalls.map((rc) => rc.name)).toContain(
|
|
441
|
+
"weather",
|
|
442
|
+
);
|
|
443
|
+
expect(approveRender()).toBe(before);
|
|
444
|
+
expect(setTools).not.toHaveBeenCalled();
|
|
445
|
+
});
|
|
446
|
+
|
|
414
447
|
it("keeps the tool call pending until respond is called", async () => {
|
|
415
448
|
// Reproduces OSS-803: the handler used to warn and resolve undefined
|
|
416
449
|
// immediately, so the HITL UI flashed and disappeared instead of waiting
|