@copilotkit/vue 1.69.1 → 1.69.3
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/PARITY.md +1 -1
- package/README.md +7 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +14 -14
- package/dist/use-render-activity-message-DMY6Krn-.cjs +85 -0
- package/dist/use-render-activity-message-DMY6Krn-.cjs.map +1 -0
- package/dist/{use-render-activity-message-CADUB--8.js → use-render-activity-message-W2lbqLZH.js} +4000 -4285
- package/dist/use-render-activity-message-W2lbqLZH.js.map +1 -0
- package/dist/v2/components/CopilotKitInspector.vue.d.ts.map +1 -1
- package/dist/v2/components/OpenGenerativeUIRenderer.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +0 -18
- 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/CopilotChatToolCallsView.vue.d.ts.map +1 -1
- package/dist/v2/components/icons/index.d.ts +1 -1
- package/dist/v2/components/icons/index.d.ts.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +1 -1
- package/dist/v2/providers/CopilotKitProvider.types.d.ts +10 -9
- package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
- package/dist/v2/providers/keys.d.ts +1 -27
- package/dist/v2/providers/keys.d.ts.map +1 -1
- package/dist/v2/providers/types.d.ts +0 -3
- package/dist/v2/providers/types.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/v2/__tests__/mocks/web-inspector.ts +32 -1
- package/src/v2/components/CopilotKitInspector.vue +34 -14
- package/src/v2/components/OpenGenerativeUIRenderer.ts +1 -42
- package/src/v2/components/__tests__/CopilotKitInspector.test.ts +31 -6
- package/src/v2/components/chat/CopilotChatAssistantMessage.vue +1 -52
- package/src/v2/components/chat/CopilotChatMessageView.vue +23 -57
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +32 -68
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +16 -70
- package/src/v2/components/icons/__tests__/icons.test.ts +0 -2
- package/src/v2/components/icons/index.ts +0 -1
- package/src/v2/providers/CopilotKitProvider.types.ts +10 -9
- package/src/v2/providers/CopilotKitProvider.vue +15 -73
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +148 -37
- package/src/v2/providers/keys.ts +1 -33
- package/src/v2/providers/types.ts +0 -3
- package/dist/use-render-activity-message-BtaJ2iQc.cjs +0 -97
- package/dist/use-render-activity-message-BtaJ2iQc.cjs.map +0 -1
- package/dist/use-render-activity-message-CADUB--8.js.map +0 -1
- package/dist/v2/components/chat/SaveSnippetBeside.vue.d.ts +0 -20
- package/dist/v2/components/chat/SaveSnippetBeside.vue.d.ts.map +0 -1
- package/dist/v2/components/chat/save-snippet-beside.d.ts +0 -20
- package/dist/v2/components/chat/save-snippet-beside.d.ts.map +0 -1
- package/src/v2/components/chat/SaveSnippetBeside.vue +0 -82
- package/src/v2/components/chat/save-snippet-beside.ts +0 -84
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
defineComponent,
|
|
5
5
|
getCurrentInstance,
|
|
6
6
|
h,
|
|
7
|
-
inject,
|
|
8
7
|
onBeforeUnmount,
|
|
9
8
|
onMounted,
|
|
10
9
|
ref,
|
|
@@ -14,7 +13,6 @@ import { StreamMarkdown } from "streamdown-vue";
|
|
|
14
13
|
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
15
14
|
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
16
15
|
import {
|
|
17
|
-
IconBookmark,
|
|
18
16
|
IconCheck,
|
|
19
17
|
IconCopy,
|
|
20
18
|
IconDownload,
|
|
@@ -36,7 +34,6 @@ import type {
|
|
|
36
34
|
CopilotChatAssistantMessageToolbarSlotProps,
|
|
37
35
|
} from "./types";
|
|
38
36
|
import { useKatexStyles } from "../../hooks/use-katex-styles";
|
|
39
|
-
import { InspectorKey } from "../../providers/keys";
|
|
40
37
|
|
|
41
38
|
useKatexStyles();
|
|
42
39
|
|
|
@@ -91,10 +88,6 @@ const emit = defineEmits<{
|
|
|
91
88
|
|
|
92
89
|
const config = useCopilotChatConfiguration();
|
|
93
90
|
const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
|
|
94
|
-
const inspector = inject(InspectorKey, null);
|
|
95
|
-
const isLocalInspectorEnabled = computed(
|
|
96
|
-
() => inspector?.isLocalInspectorEnabled.value === true,
|
|
97
|
-
);
|
|
98
91
|
const instance = getCurrentInstance();
|
|
99
92
|
const copied = ref(false);
|
|
100
93
|
let copiedResetTimeout: ReturnType<typeof setTimeout> | null = null;
|
|
@@ -668,31 +661,10 @@ const isLatestAssistantMessage = computed(
|
|
|
668
661
|
const shouldShowToolbar = computed(
|
|
669
662
|
() =>
|
|
670
663
|
props.toolbarVisible &&
|
|
671
|
-
|
|
664
|
+
hasContent.value &&
|
|
672
665
|
!(props.isRunning && isLatestAssistantMessage.value),
|
|
673
666
|
);
|
|
674
667
|
|
|
675
|
-
function handleViewInspector() {
|
|
676
|
-
inspector?.openInspector({
|
|
677
|
-
messageId: props.message.id,
|
|
678
|
-
threadId: config.value?.threadId,
|
|
679
|
-
agentId: config.value?.agentId,
|
|
680
|
-
});
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
function handleSaveSnippet() {
|
|
684
|
-
if (!hasContent.value) {
|
|
685
|
-
return;
|
|
686
|
-
}
|
|
687
|
-
void inspector?.saveEventSnippet({
|
|
688
|
-
kind: "text",
|
|
689
|
-
messageId: props.message.id,
|
|
690
|
-
content: props.message.content ?? "",
|
|
691
|
-
threadId: config.value?.threadId,
|
|
692
|
-
agentId: config.value?.agentId,
|
|
693
|
-
});
|
|
694
|
-
}
|
|
695
|
-
|
|
696
668
|
function resetCopiedStateWithDelay() {
|
|
697
669
|
if (copiedResetTimeout) {
|
|
698
670
|
clearTimeout(copiedResetTimeout);
|
|
@@ -842,29 +814,6 @@ onBeforeUnmount(() => {
|
|
|
842
814
|
</button>
|
|
843
815
|
</slot>
|
|
844
816
|
|
|
845
|
-
<button
|
|
846
|
-
v-if="isLocalInspectorEnabled"
|
|
847
|
-
data-testid="copilot-inspector-button"
|
|
848
|
-
type="button"
|
|
849
|
-
:class="toolbarButtonClass"
|
|
850
|
-
:aria-label="`${labels.assistantMessageToolbarInspectorLabel} (${labels.assistantMessageToolbarInspectorLocalOnlyLabel})`"
|
|
851
|
-
:title="`${labels.assistantMessageToolbarInspectorLabel} (${labels.assistantMessageToolbarInspectorLocalOnlyLabel})`"
|
|
852
|
-
@click="handleViewInspector"
|
|
853
|
-
>
|
|
854
|
-
I
|
|
855
|
-
</button>
|
|
856
|
-
<button
|
|
857
|
-
v-if="isLocalInspectorEnabled && hasContent"
|
|
858
|
-
data-testid="copilot-save-snippet-button"
|
|
859
|
-
type="button"
|
|
860
|
-
:class="toolbarButtonClass"
|
|
861
|
-
:aria-label="`${labels.assistantMessageToolbarSaveSnippetLabel} (${labels.assistantMessageToolbarInspectorLocalOnlyLabel})`"
|
|
862
|
-
:title="`${labels.assistantMessageToolbarSaveSnippetLabel} (${labels.assistantMessageToolbarInspectorLocalOnlyLabel})`"
|
|
863
|
-
@click="handleSaveSnippet"
|
|
864
|
-
>
|
|
865
|
-
<IconBookmark class="cpk:size-[18px]" />
|
|
866
|
-
</button>
|
|
867
|
-
|
|
868
817
|
<slot
|
|
869
818
|
v-if="hasThumbsUp"
|
|
870
819
|
name="thumbs-up-button"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed,
|
|
2
|
+
import { computed, ref, useSlots, watch } from "vue";
|
|
3
3
|
import type { Component } from "vue";
|
|
4
4
|
import type {
|
|
5
5
|
ActivityMessage,
|
|
@@ -19,9 +19,6 @@ import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfi
|
|
|
19
19
|
import CopilotChatAssistantMessage from "./CopilotChatAssistantMessage.vue";
|
|
20
20
|
import CopilotChatReasoningMessage from "./CopilotChatReasoningMessage.vue";
|
|
21
21
|
import CopilotChatUserMessage from "./CopilotChatUserMessage.vue";
|
|
22
|
-
import { InspectorKey } from "../../providers/keys";
|
|
23
|
-
import { IconBookmark } from "../icons";
|
|
24
|
-
import SaveSnippetBeside from "./SaveSnippetBeside.vue";
|
|
25
22
|
|
|
26
23
|
interface MessageMetaProps {
|
|
27
24
|
message: Message;
|
|
@@ -41,23 +38,6 @@ interface ActivitySlotProps {
|
|
|
41
38
|
agent: unknown;
|
|
42
39
|
}
|
|
43
40
|
|
|
44
|
-
const inspector = inject(InspectorKey, null);
|
|
45
|
-
const canSaveActivity = (message: ActivityMessage) =>
|
|
46
|
-
inspector?.isLocalInspectorEnabled.value === true &&
|
|
47
|
-
(message.activityType === "a2ui-surface" ||
|
|
48
|
-
message.activityType === "open-generative-ui");
|
|
49
|
-
|
|
50
|
-
function saveActivitySnippet(message: ActivityMessage) {
|
|
51
|
-
void inspector?.saveEventSnippet({
|
|
52
|
-
kind: "activity",
|
|
53
|
-
messageId: message.id,
|
|
54
|
-
activityType: message.activityType,
|
|
55
|
-
content: message.content,
|
|
56
|
-
threadId: config.value?.threadId,
|
|
57
|
-
agentId: config.value?.agentId,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
|
|
61
41
|
type InterruptSlotProps = InterruptRenderProps<unknown, unknown>;
|
|
62
42
|
type CustomMessagePosition = VueCustomMessageRendererProps["position"];
|
|
63
43
|
type ResolvedCustomMessageRenderer = {
|
|
@@ -434,42 +414,28 @@ function resolveToolMessage(
|
|
|
434
414
|
/>
|
|
435
415
|
</slot>
|
|
436
416
|
|
|
437
|
-
<
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
</slot>
|
|
460
|
-
<template #save>
|
|
461
|
-
<button
|
|
462
|
-
type="button"
|
|
463
|
-
class="cpk:inline-flex cpk:h-8 cpk:w-8 cpk:items-center cpk:justify-center cpk:rounded-md cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8] cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]"
|
|
464
|
-
data-testid="copilot-activity-save-snippet-button"
|
|
465
|
-
:aria-label="`${config?.labels.assistantMessageToolbarSaveSnippetLabel ?? 'Save as snippet'} (Local Only)`"
|
|
466
|
-
@click="saveActivitySnippet(message)"
|
|
467
|
-
>
|
|
468
|
-
<IconBookmark class="cpk:size-[18px]" />
|
|
469
|
-
</button>
|
|
470
|
-
</template>
|
|
471
|
-
</SaveSnippetBeside>
|
|
472
|
-
</div>
|
|
417
|
+
<slot
|
|
418
|
+
v-else-if="message.role === 'activity'"
|
|
419
|
+
:name="getActivitySlotName(message.activityType)"
|
|
420
|
+
:activity-type="message.activityType"
|
|
421
|
+
:content="message.content"
|
|
422
|
+
:message="message"
|
|
423
|
+
:agent="resolvedThreadAgent"
|
|
424
|
+
>
|
|
425
|
+
<slot
|
|
426
|
+
name="activity-message"
|
|
427
|
+
:activity-type="message.activityType"
|
|
428
|
+
:content="message.content"
|
|
429
|
+
:message="message"
|
|
430
|
+
:agent="resolvedThreadAgent"
|
|
431
|
+
>
|
|
432
|
+
<component
|
|
433
|
+
v-if="resolveActivityRenderer(message)"
|
|
434
|
+
:is="resolveActivityRenderer(message)!.renderer"
|
|
435
|
+
v-bind="resolveActivityRenderer(message)!.props"
|
|
436
|
+
/>
|
|
437
|
+
</slot>
|
|
438
|
+
</slot>
|
|
473
439
|
|
|
474
440
|
<slot
|
|
475
441
|
v-if="componentSlots['message-after']"
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { computed,
|
|
2
|
+
import { computed, onBeforeUnmount, ref, watch } from "vue";
|
|
3
3
|
import type { Message, ReasoningMessage } from "@ag-ui/core";
|
|
4
4
|
import { StreamMarkdown } from "streamdown-vue";
|
|
5
|
-
import {
|
|
6
|
-
import { InspectorKey } from "../../providers/keys";
|
|
7
|
-
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
8
|
-
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
5
|
+
import { IconChevronRight } from "../icons";
|
|
9
6
|
|
|
10
7
|
const props = withDefaults(
|
|
11
8
|
defineProps<{
|
|
@@ -142,27 +139,6 @@ function toggleOpen() {
|
|
|
142
139
|
userToggledDuringStreaming.value = true;
|
|
143
140
|
isOpen.value = !isOpen.value;
|
|
144
141
|
}
|
|
145
|
-
|
|
146
|
-
const inspector = inject(InspectorKey, null);
|
|
147
|
-
const chatConfiguration = useCopilotChatConfiguration();
|
|
148
|
-
const canSaveReasoning = computed(
|
|
149
|
-
() => inspector?.isLocalInspectorEnabled.value === true && hasContent.value,
|
|
150
|
-
);
|
|
151
|
-
const saveLabel = computed(
|
|
152
|
-
() =>
|
|
153
|
-
chatConfiguration.value?.labels.assistantMessageToolbarSaveSnippetLabel ??
|
|
154
|
-
CopilotChatDefaultLabels.assistantMessageToolbarSaveSnippetLabel,
|
|
155
|
-
);
|
|
156
|
-
|
|
157
|
-
function saveReasoningSnippet() {
|
|
158
|
-
void inspector?.saveEventSnippet({
|
|
159
|
-
kind: "reasoning",
|
|
160
|
-
messageId: props.message.id,
|
|
161
|
-
content: normalizedContent.value,
|
|
162
|
-
threadId: chatConfiguration.value?.threadId,
|
|
163
|
-
agentId: chatConfiguration.value?.agentId,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
142
|
</script>
|
|
167
143
|
|
|
168
144
|
<template>
|
|
@@ -193,53 +169,41 @@ function saveReasoningSnippet() {
|
|
|
193
169
|
},
|
|
194
170
|
}"
|
|
195
171
|
>
|
|
196
|
-
<
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
172
|
+
<slot
|
|
173
|
+
name="header"
|
|
174
|
+
:is-open="isOpen"
|
|
175
|
+
:label="label"
|
|
176
|
+
:has-content="hasContent"
|
|
177
|
+
:is-streaming="isStreaming"
|
|
178
|
+
:on-click="hasContent ? toggleOpen : undefined"
|
|
179
|
+
>
|
|
180
|
+
<button
|
|
181
|
+
type="button"
|
|
182
|
+
class="cpk:inline-flex cpk:items-center cpk:gap-1 cpk:py-1 cpk:text-sm cpk:text-muted-foreground cpk:transition-colors cpk:select-none"
|
|
183
|
+
:class="
|
|
184
|
+
hasContent
|
|
185
|
+
? 'cpk:hover:text-foreground cpk:cursor-pointer'
|
|
186
|
+
: 'cpk:cursor-default'
|
|
187
|
+
"
|
|
188
|
+
:aria-expanded="hasContent ? isOpen : undefined"
|
|
189
|
+
@click="hasContent ? toggleOpen() : undefined"
|
|
204
190
|
>
|
|
205
|
-
<
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
hasContent
|
|
210
|
-
? 'cpk:hover:text-foreground cpk:cursor-pointer'
|
|
211
|
-
: 'cpk:cursor-default'
|
|
212
|
-
"
|
|
213
|
-
:aria-expanded="hasContent ? isOpen : undefined"
|
|
214
|
-
@click="hasContent ? toggleOpen() : undefined"
|
|
191
|
+
<span class="cpk:font-medium">{{ label }}</span>
|
|
192
|
+
<span
|
|
193
|
+
v-if="isStreaming && !hasContent"
|
|
194
|
+
class="cpk:inline-flex cpk:items-center cpk:ml-1"
|
|
215
195
|
>
|
|
216
|
-
<span class="cpk:font-medium">{{ label }}</span>
|
|
217
196
|
<span
|
|
218
|
-
|
|
219
|
-
class="cpk:inline-flex cpk:items-center cpk:ml-1"
|
|
220
|
-
>
|
|
221
|
-
<span
|
|
222
|
-
class="cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse"
|
|
223
|
-
/>
|
|
224
|
-
</span>
|
|
225
|
-
<IconChevronRight
|
|
226
|
-
v-if="hasContent"
|
|
227
|
-
class="cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200"
|
|
228
|
-
:class="{ 'cpk:rotate-90': isOpen }"
|
|
197
|
+
class="cpk:w-1.5 cpk:h-1.5 cpk:rounded-full cpk:bg-muted-foreground cpk:animate-pulse"
|
|
229
198
|
/>
|
|
230
|
-
</
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
data-testid="copilot-save-snippet-button"
|
|
237
|
-
:aria-label="`${saveLabel} (Local Only)`"
|
|
238
|
-
@click="saveReasoningSnippet"
|
|
239
|
-
>
|
|
240
|
-
<IconBookmark class="cpk:size-[18px]" />
|
|
199
|
+
</span>
|
|
200
|
+
<IconChevronRight
|
|
201
|
+
v-if="hasContent"
|
|
202
|
+
class="cpk:size-3.5 cpk:shrink-0 cpk:transition-transform cpk:duration-200"
|
|
203
|
+
:class="{ 'cpk:rotate-90': isOpen }"
|
|
204
|
+
/>
|
|
241
205
|
</button>
|
|
242
|
-
</
|
|
206
|
+
</slot>
|
|
243
207
|
|
|
244
208
|
<slot
|
|
245
209
|
name="toggle"
|
|
@@ -1,15 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import {
|
|
2
|
+
import { useSlots } from "vue";
|
|
3
3
|
import type { AssistantMessage, Message } from "@ag-ui/core";
|
|
4
4
|
import type { CopilotChatToolCallRenderSlotProps } from "./types";
|
|
5
5
|
import CopilotChatToolCallItem from "./CopilotChatToolCallItem.vue";
|
|
6
|
-
import SaveSnippetBeside from "./SaveSnippetBeside.vue";
|
|
7
|
-
import { InspectorKey } from "../../providers/keys";
|
|
8
|
-
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
9
|
-
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
10
|
-
import { IconBookmark } from "../icons";
|
|
11
6
|
|
|
12
|
-
|
|
7
|
+
withDefaults(
|
|
13
8
|
defineProps<{
|
|
14
9
|
message: AssistantMessage;
|
|
15
10
|
messages?: Message[];
|
|
@@ -34,70 +29,21 @@ const componentSlots = useSlots() as Record<
|
|
|
34
29
|
function getForwardedSlotNames(): ToolCallSlotName[] {
|
|
35
30
|
return Object.keys(componentSlots) as ToolCallSlotName[];
|
|
36
31
|
}
|
|
37
|
-
|
|
38
|
-
// A streaming tool call has truncated arguments. Do not offer to capture it
|
|
39
|
-
// until the JSON is complete, or the snippet holds a broken partial payload.
|
|
40
|
-
function hasCompleteArgs(args: string | undefined): boolean {
|
|
41
|
-
const trimmed = (args ?? "").trim();
|
|
42
|
-
if (!trimmed) {
|
|
43
|
-
return true;
|
|
44
|
-
}
|
|
45
|
-
try {
|
|
46
|
-
JSON.parse(trimmed);
|
|
47
|
-
return true;
|
|
48
|
-
} catch {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const inspector = inject(InspectorKey, null);
|
|
54
|
-
const chatConfiguration = useCopilotChatConfiguration();
|
|
55
|
-
const canSave = (toolCall: { function: { arguments: string } }) =>
|
|
56
|
-
inspector?.isLocalInspectorEnabled.value === true &&
|
|
57
|
-
hasCompleteArgs(toolCall.function.arguments);
|
|
58
|
-
const saveLabel = () =>
|
|
59
|
-
chatConfiguration.value?.labels.assistantMessageToolbarSaveSnippetLabel ??
|
|
60
|
-
CopilotChatDefaultLabels.assistantMessageToolbarSaveSnippetLabel;
|
|
61
|
-
|
|
62
|
-
function saveToolCall(toolCall: {
|
|
63
|
-
id: string;
|
|
64
|
-
function: { name: string; arguments: string };
|
|
65
|
-
}) {
|
|
66
|
-
void inspector?.saveEventSnippet({
|
|
67
|
-
kind: "tool-call",
|
|
68
|
-
messageId: props.message.id,
|
|
69
|
-
toolCallId: toolCall.id,
|
|
70
|
-
toolName: toolCall.function.name,
|
|
71
|
-
argsJson: toolCall.function.arguments || "{}",
|
|
72
|
-
threadId: chatConfiguration.value?.threadId,
|
|
73
|
-
agentId: chatConfiguration.value?.agentId,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
32
|
</script>
|
|
77
33
|
|
|
78
34
|
<template>
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
<
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
class="cpk:inline-flex cpk:h-8 cpk:w-8 cpk:items-center cpk:justify-center cpk:rounded-md cpk:p-0 cpk:text-[rgb(93,93,93)] cpk:hover:bg-[#E8E8E8] cpk:dark:text-[rgb(243,243,243)] cpk:dark:hover:bg-[#303030]"
|
|
94
|
-
data-testid="copilot-tool-save-snippet-button"
|
|
95
|
-
:aria-label="`${saveLabel()} (Local Only)`"
|
|
96
|
-
@click="saveToolCall(toolCall)"
|
|
97
|
-
>
|
|
98
|
-
<IconBookmark class="cpk:size-[18px]" />
|
|
99
|
-
</button>
|
|
100
|
-
</template>
|
|
101
|
-
</SaveSnippetBeside>
|
|
102
|
-
</div>
|
|
35
|
+
<CopilotChatToolCallItem
|
|
36
|
+
v-for="toolCall in message.toolCalls ?? []"
|
|
37
|
+
:key="toolCall.id"
|
|
38
|
+
:tool-call="toolCall"
|
|
39
|
+
:messages="messages"
|
|
40
|
+
>
|
|
41
|
+
<template
|
|
42
|
+
v-for="slotName in getForwardedSlotNames()"
|
|
43
|
+
:key="slotName"
|
|
44
|
+
#[slotName]="slotProps"
|
|
45
|
+
>
|
|
46
|
+
<slot :name="slotName" v-bind="slotProps ?? {}" />
|
|
47
|
+
</template>
|
|
48
|
+
</CopilotChatToolCallItem>
|
|
103
49
|
</template>
|
|
@@ -2,7 +2,6 @@ import { describe, expect, it } from "vitest";
|
|
|
2
2
|
import { mount } from "@vue/test-utils";
|
|
3
3
|
import {
|
|
4
4
|
IconArrowUp,
|
|
5
|
-
IconBookmark,
|
|
6
5
|
IconCheck,
|
|
7
6
|
IconCheckCircle,
|
|
8
7
|
IconChevronDown,
|
|
@@ -32,7 +31,6 @@ describe("icons adapter", () => {
|
|
|
32
31
|
IconPlus,
|
|
33
32
|
IconMic,
|
|
34
33
|
IconArrowUp,
|
|
35
|
-
IconBookmark,
|
|
36
34
|
IconCheck,
|
|
37
35
|
IconSquare,
|
|
38
36
|
IconLoader2,
|
|
@@ -37,7 +37,17 @@ export interface CopilotKitProviderProps {
|
|
|
37
37
|
sandboxFunctions?: SandboxFunction[];
|
|
38
38
|
designSkill?: string;
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* @deprecated This prop no longer controls the Inspector. Use
|
|
42
|
+
* `enableInspector` instead.
|
|
43
|
+
*/
|
|
40
44
|
showDevConsole?: boolean | "auto";
|
|
45
|
+
/**
|
|
46
|
+
* Disable the CopilotKit Inspector in development.
|
|
47
|
+
* The Inspector is enabled by default in development browser builds and is
|
|
48
|
+
* always disabled in production and during server rendering.
|
|
49
|
+
*/
|
|
50
|
+
enableInspector?: boolean;
|
|
41
51
|
onError?: (event: {
|
|
42
52
|
error: Error;
|
|
43
53
|
code: CopilotKitCoreErrorCode;
|
|
@@ -49,15 +59,6 @@ export interface CopilotKitProviderProps {
|
|
|
49
59
|
loadingComponent?: Component;
|
|
50
60
|
includeSchema?: boolean;
|
|
51
61
|
};
|
|
52
|
-
/**
|
|
53
|
-
* Default anchor corner for the inspector button and window.
|
|
54
|
-
* Only used on first load before the user drags to a custom position.
|
|
55
|
-
* Defaults to `{ horizontal: "right", vertical: "top" }`.
|
|
56
|
-
*/
|
|
57
|
-
inspectorDefaultAnchor?: {
|
|
58
|
-
horizontal: "left" | "right";
|
|
59
|
-
vertical: "top" | "bottom";
|
|
60
|
-
};
|
|
61
62
|
/**
|
|
62
63
|
* Enable debug logging for the client-side event pipeline.
|
|
63
64
|
*
|
|
@@ -15,7 +15,7 @@ import type {
|
|
|
15
15
|
CopilotKitCoreSubscriber,
|
|
16
16
|
FrontendTool,
|
|
17
17
|
} from "@copilotkit/core";
|
|
18
|
-
import { schemaToJsonSchema } from "@copilotkit/shared";
|
|
18
|
+
import { schemaToJsonSchema, shouldEnableInspector } from "@copilotkit/shared";
|
|
19
19
|
import type { RuntimeLicenseStatus } from "@copilotkit/shared";
|
|
20
20
|
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
21
21
|
import { CopilotKitCoreVue } from "../lib/vue-core";
|
|
@@ -35,7 +35,7 @@ import {
|
|
|
35
35
|
MCPAppsActivityType,
|
|
36
36
|
} from "../components/MCPAppsActivityRenderer";
|
|
37
37
|
import { CopilotKitKey, InspectorKey, SandboxFunctionsKey } from "./keys";
|
|
38
|
-
import type { VueInspectorOpenRequest
|
|
38
|
+
import type { VueInspectorOpenRequest } from "./keys";
|
|
39
39
|
import {
|
|
40
40
|
LicenseContextKey,
|
|
41
41
|
createLicenseContextValue,
|
|
@@ -54,7 +54,6 @@ import type {
|
|
|
54
54
|
|
|
55
55
|
const HEADER_NAME = "X-CopilotCloud-Public-Api-Key";
|
|
56
56
|
const COPILOT_CLOUD_CHAT_URL = "https://api.cloud.copilotkit.ai/copilotkit/v1";
|
|
57
|
-
|
|
58
57
|
// Canonical A2UI viewer theme default (matches @copilotkit/a2ui-renderer).
|
|
59
58
|
// Defined locally to avoid pulling React dependencies from a2ui-renderer.
|
|
60
59
|
const viewerTheme: Record<string, unknown> = {};
|
|
@@ -104,90 +103,34 @@ const props = withDefaults(defineProps<CopilotKitProviderProps>(), {
|
|
|
104
103
|
renderCustomMessages: () => [],
|
|
105
104
|
renderActivityMessages: () => [],
|
|
106
105
|
openGenerativeUI: undefined,
|
|
107
|
-
showDevConsole: false,
|
|
108
106
|
useSingleEndpoint: undefined,
|
|
109
107
|
a2ui: undefined,
|
|
108
|
+
enableInspector: undefined,
|
|
110
109
|
});
|
|
111
110
|
|
|
112
111
|
const shouldRenderInspector = ref(false);
|
|
113
|
-
// Mounting the overlay follows showDevConsole. The in-chat affordances are
|
|
114
|
-
// narrower: a dev build on localhost only, so `showDevConsole: true` on a
|
|
115
|
-
// staging URL never puts a bookmark into a production chat. Matches React.
|
|
116
|
-
const canShowLocalInspectorAction = ref(false);
|
|
117
|
-
|
|
118
|
-
const updateInspectorVisibility = () => {
|
|
119
|
-
const isLocalhost =
|
|
120
|
-
typeof window !== "undefined" &&
|
|
121
|
-
new Set(["localhost", "127.0.0.1"]).has(window.location?.hostname ?? "");
|
|
122
|
-
canShowLocalInspectorAction.value =
|
|
123
|
-
process.env.NODE_ENV === "development" && isLocalhost;
|
|
124
|
-
|
|
125
|
-
if (props.showDevConsole === true) {
|
|
126
|
-
shouldRenderInspector.value = true;
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
if (props.showDevConsole === "auto") {
|
|
130
|
-
shouldRenderInspector.value = isLocalhost;
|
|
131
|
-
if (!isLocalhost) {
|
|
132
|
-
canShowLocalInspectorAction.value = false;
|
|
133
|
-
}
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
shouldRenderInspector.value = false;
|
|
137
|
-
canShowLocalInspectorAction.value = false;
|
|
138
|
-
};
|
|
139
112
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
113
|
+
function updateInspectorVisibility(): void {
|
|
114
|
+
shouldRenderInspector.value = shouldEnableInspector({
|
|
115
|
+
enableInspector: props.enableInspector,
|
|
116
|
+
isBrowser: true,
|
|
117
|
+
isDevelopment: process.env.NODE_ENV === "development",
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
onMounted(updateInspectorVisibility);
|
|
122
|
+
watch(() => props.enableInspector, updateInspectorVisibility);
|
|
143
123
|
|
|
144
124
|
const inspectorOpenRequest = ref<VueInspectorOpenRequest | null>(null);
|
|
145
|
-
const
|
|
146
|
-
() => shouldRenderInspector.value && canShowLocalInspectorAction.value,
|
|
147
|
-
);
|
|
125
|
+
const isInspectorEnabled = computed(() => shouldRenderInspector.value);
|
|
148
126
|
|
|
149
127
|
function openInspector(request: VueInspectorOpenRequest) {
|
|
150
128
|
inspectorOpenRequest.value = { ...request };
|
|
151
129
|
}
|
|
152
130
|
|
|
153
|
-
async function saveEventSnippet(request: VueInspectorSaveRequest) {
|
|
154
|
-
try {
|
|
155
|
-
const mod = await import("@copilotkit/web-inspector");
|
|
156
|
-
const threadId = request.threadId ?? "inspector-snippet";
|
|
157
|
-
const runId = `inspector-snippet-${Date.now()}`;
|
|
158
|
-
const compiled = mod.compileChatSnippet({
|
|
159
|
-
...request,
|
|
160
|
-
threadId,
|
|
161
|
-
runId,
|
|
162
|
-
});
|
|
163
|
-
const now = new Date().toISOString();
|
|
164
|
-
const snippet = {
|
|
165
|
-
id: crypto.randomUUID(),
|
|
166
|
-
name: compiled.name,
|
|
167
|
-
recipe: compiled.recipe,
|
|
168
|
-
events: compiled.events,
|
|
169
|
-
createdAt: now,
|
|
170
|
-
updatedAt: now,
|
|
171
|
-
};
|
|
172
|
-
mod.upsertEventSnippet(snippet);
|
|
173
|
-
openInspector({
|
|
174
|
-
messageId: request.messageId,
|
|
175
|
-
threadId: request.threadId,
|
|
176
|
-
agentId: request.agentId,
|
|
177
|
-
menu: "event-snippets",
|
|
178
|
-
snippetId: snippet.id,
|
|
179
|
-
});
|
|
180
|
-
} catch (error) {
|
|
181
|
-
// Compile can throw on bad args, and storage can throw QuotaExceededError.
|
|
182
|
-
// Callers fire this as `void saveEventSnippet(...)`, so report it here.
|
|
183
|
-
console.error("[CopilotKit] Could not save the event snippet.", error);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
|
|
187
131
|
provide(InspectorKey, {
|
|
188
|
-
|
|
132
|
+
isInspectorEnabled,
|
|
189
133
|
openInspector,
|
|
190
|
-
saveEventSnippet,
|
|
191
134
|
});
|
|
192
135
|
|
|
193
136
|
const initialFrontendTools = props.frontendTools;
|
|
@@ -715,7 +658,6 @@ const showExpiringBanner = computed(
|
|
|
715
658
|
<CopilotKitInspector
|
|
716
659
|
v-if="shouldRenderInspector"
|
|
717
660
|
:core="copilotkit"
|
|
718
|
-
:default-anchor="props.inspectorDefaultAnchor"
|
|
719
661
|
:open-request="inspectorOpenRequest"
|
|
720
662
|
/>
|
|
721
663
|
<!-- License warnings — driven by server-reported status -->
|