@copilotkit/vue 2.0.0-rc.6 → 2.0.0-rc.8
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/dist/index.cjs +1 -73
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +292 -16949
- package/dist/index.mjs.map +1 -1
- package/dist/use-render-activity-message-C5LCG9a9.js +16451 -0
- package/dist/use-render-activity-message-C5LCG9a9.js.map +1 -0
- package/dist/use-render-activity-message-CPzguixR.cjs +74 -0
- package/dist/use-render-activity-message-CPzguixR.cjs.map +1 -0
- package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAttachmentQueue.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatAttachmentRenderer.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +6 -270
- package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatMessageView.vue.d.ts +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/CopilotChatToolCallGroup.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallGroup.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallItem.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts +1 -1
- package/dist/v2/components/chat/CopilotChatToolCallsView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/CopilotChatWorkSummary.vue.d.ts.map +1 -1
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts +0 -1
- package/dist/v2/components/chat/copilotChatToolCallItemRender.d.ts.map +1 -1
- package/dist/v2/components/chat/index.d.ts +0 -1
- package/dist/v2/components/chat/index.d.ts.map +1 -1
- package/dist/v2/components/chat/tool-call-display-context.d.ts +2 -19
- package/dist/v2/components/chat/tool-call-display-context.d.ts.map +1 -1
- package/dist/v2/components/chat/tool-call-group-parts.d.ts +7 -20
- package/dist/v2/components/chat/tool-call-group-parts.d.ts.map +1 -1
- package/dist/v2/components/chat/turn-work.d.ts +0 -2
- package/dist/v2/components/chat/turn-work.d.ts.map +1 -1
- package/dist/v2/components/chat/types.d.ts +1 -2
- package/dist/v2/components/chat/types.d.ts.map +1 -1
- package/dist/v2/components/chat/use-chat-labels.d.ts +8 -0
- package/dist/v2/components/chat/use-chat-labels.d.ts.map +1 -0
- package/dist/v2/components/icons/index.d.ts +968 -1
- package/dist/v2/components/icons/index.d.ts.map +1 -1
- package/dist/v2/hooks/use-frontend-tool.d.ts +5 -0
- package/dist/v2/hooks/use-frontend-tool.d.ts.map +1 -1
- package/dist/v2/hooks/use-render-activity-message.d.ts +13 -9
- package/dist/v2/hooks/use-render-activity-message.d.ts.map +1 -1
- package/dist/v2/hooks/use-render-custom-messages.d.ts +5 -7
- package/dist/v2/hooks/use-render-custom-messages.d.ts.map +1 -1
- package/dist/v2/index.cjs +1 -1
- package/dist/v2/index.mjs +196 -199
- package/dist/v2/index.mjs.map +1 -1
- package/dist/v2/lib/vue-core.d.ts +0 -1
- package/dist/v2/lib/vue-core.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.types.d.ts +0 -5
- package/dist/v2/providers/CopilotKitProvider.types.d.ts.map +1 -1
- package/dist/v2/providers/CopilotKitProvider.vue.d.ts.map +1 -1
- package/dist/v2/providers/types.d.ts +3 -46
- package/dist/v2/providers/types.d.ts.map +1 -1
- package/dist/v2/types/human-in-the-loop.d.ts +8 -29
- package/dist/v2/types/human-in-the-loop.d.ts.map +1 -1
- package/dist/v2/types/interrupt.d.ts +1 -22
- package/dist/v2/types/interrupt.d.ts.map +1 -1
- package/dist/v2/types/vue-activity-message-renderer.d.ts +16 -15
- package/dist/v2/types/vue-activity-message-renderer.d.ts.map +1 -1
- package/dist/v2/types/vue-custom-message-renderer.d.ts +7 -16
- package/dist/v2/types/vue-custom-message-renderer.d.ts.map +1 -1
- package/dist/v2/types/vue-tool-call-renderer.d.ts +16 -35
- package/dist/v2/types/vue-tool-call-renderer.d.ts.map +1 -1
- package/package.json +7 -8
- package/src/__tests__/build-entries.test.ts +27 -0
- package/src/v2/components/LicenseWarningBanner.vue +31 -15
- package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +20 -0
- package/src/v2/components/chat/CopilotChat.vue +19 -40
- package/src/v2/components/chat/CopilotChatAttachmentQueue.vue +14 -10
- package/src/v2/components/chat/CopilotChatAttachmentRenderer.vue +14 -6
- package/src/v2/components/chat/CopilotChatInput.vue +40 -30
- package/src/v2/components/chat/CopilotChatMessageView.vue +72 -140
- package/src/v2/components/chat/CopilotChatReasoningMessage.vue +31 -13
- package/src/v2/components/chat/CopilotChatToolCallGroup.vue +60 -37
- package/src/v2/components/chat/CopilotChatToolCallItem.vue +3 -3
- package/src/v2/components/chat/CopilotChatToolCallsView.vue +15 -13
- package/src/v2/components/chat/CopilotChatView.vue +5 -5
- package/src/v2/components/chat/CopilotChatWorkSummary.vue +44 -18
- package/src/v2/components/chat/__tests__/CopilotChat.labels.test.ts +19 -4
- package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +33 -1
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.test.ts +247 -403
- package/src/v2/components/chat/__tests__/CopilotChatMessageView.toolCallDisplay.test.ts +1 -99
- package/src/v2/components/chat/copilotChatToolCallItemRender.ts +3 -19
- package/src/v2/components/chat/index.ts +0 -1
- package/src/v2/components/chat/tool-call-display-context.ts +2 -23
- package/src/v2/components/chat/tool-call-group-parts.ts +44 -85
- package/src/v2/components/chat/turn-work.ts +0 -9
- package/src/v2/components/chat/types.ts +4 -4
- package/src/v2/components/chat/use-chat-labels.ts +16 -0
- package/src/v2/components/icons/__tests__/icons.test.ts +72 -68
- package/src/v2/components/icons/index.ts +109 -27
- package/src/v2/hooks/__tests__/use-frontend-tool.e2e.test.ts +62 -1
- package/src/v2/hooks/__tests__/use-render-activity-message.test.ts +105 -0
- package/src/v2/hooks/__tests__/use-render-tool.test.ts +3 -6
- package/src/v2/hooks/__tests__/zod-regression.test.ts +4 -3
- package/src/v2/hooks/use-frontend-tool.ts +10 -10
- package/src/v2/hooks/use-render-activity-message.ts +27 -48
- package/src/v2/hooks/use-render-custom-messages.ts +14 -35
- package/src/v2/lib/vue-core.ts +3 -5
- package/src/v2/providers/CopilotKitProvider.types.ts +0 -5
- package/src/v2/providers/CopilotKitProvider.vue +29 -80
- package/src/v2/providers/__tests__/CopilotKitProvider.headersAtSendTime.test.ts +3 -3
- package/src/v2/providers/__tests__/CopilotKitProvider.learning.test.ts +3 -1
- package/src/v2/providers/__tests__/CopilotKitProvider.test.ts +17 -33
- package/src/v2/providers/types.ts +3 -49
- package/src/v2/types/__tests__/defineToolCallRenderer.test.ts +28 -33
- package/src/v2/types/defineToolCallRenderer.ts +5 -4
- package/src/v2/types/human-in-the-loop.ts +8 -32
- package/src/v2/types/interrupt.ts +7 -31
- package/src/v2/types/vue-activity-message-renderer.ts +24 -15
- package/src/v2/types/vue-custom-message-renderer.ts +12 -16
- package/src/v2/types/vue-tool-call-renderer.ts +23 -38
- package/vite.config.ts +1 -2
- package/dist/v2/components/chat/BasicMarkdown.vue.d.ts +0 -9
- package/dist/v2/components/chat/BasicMarkdown.vue.d.ts.map +0 -1
- package/dist/v2/components/chat/tool-call-layout.d.ts +0 -115
- package/dist/v2/components/chat/tool-call-layout.d.ts.map +0 -1
- package/dist/v2/lib/transcription-client.d.ts +0 -19
- package/dist/v2/lib/transcription-client.d.ts.map +0 -1
- package/src/v2/components/chat/BasicMarkdown.vue +0 -160
- package/src/v2/components/chat/__tests__/BasicMarkdown.test.ts +0 -69
- package/src/v2/components/chat/tool-call-layout.ts +0 -304
- package/src/v2/lib/__tests__/transcription-client.test.ts +0 -67
- package/src/v2/lib/transcription-client.ts +0 -151
|
@@ -10,8 +10,15 @@
|
|
|
10
10
|
* a custom wildcard renderer draws whatever it draws.
|
|
11
11
|
*/
|
|
12
12
|
import { computed, provide, ref } from "vue";
|
|
13
|
+
import {
|
|
14
|
+
ɵformatLabel,
|
|
15
|
+
ɵformatToolNames,
|
|
16
|
+
ɵgetToolCallPreview,
|
|
17
|
+
ɵgetToolCallRowStatus,
|
|
18
|
+
ɵformatCountLabel,
|
|
19
|
+
} from "@copilotkit/core";
|
|
20
|
+
import type { ToolCallEntry, ɵToolCallRowStatus } from "@copilotkit/core";
|
|
13
21
|
import { useCopilotId } from "../ui/use-id";
|
|
14
|
-
import type { ToolCallEntry } from "./tool-call-layout";
|
|
15
22
|
import { ToolCallGroupContextKey } from "./tool-call-display-context";
|
|
16
23
|
import type { ToolCallGroupContextValue } from "./tool-call-display-context";
|
|
17
24
|
import {
|
|
@@ -19,13 +26,9 @@ import {
|
|
|
19
26
|
ToolCallChevron,
|
|
20
27
|
ToolCallFailedCount,
|
|
21
28
|
ToolCallStatusIcon,
|
|
22
|
-
|
|
23
|
-
entryStatus,
|
|
24
|
-
pluralize,
|
|
25
|
-
statusLabels,
|
|
26
|
-
toolNames,
|
|
29
|
+
toolCallStatusLabel,
|
|
27
30
|
} from "./tool-call-group-parts";
|
|
28
|
-
import
|
|
31
|
+
import { useChatLabels } from "./use-chat-labels";
|
|
29
32
|
import type { CopilotChatToolCallGroupAppearance } from "./types";
|
|
30
33
|
|
|
31
34
|
const props = withDefaults(
|
|
@@ -49,6 +52,7 @@ defineSlots<{
|
|
|
49
52
|
call(props: { call: ToolCallEntry }): unknown;
|
|
50
53
|
}>();
|
|
51
54
|
|
|
55
|
+
const labels = useChatLabels();
|
|
52
56
|
const open = ref(false);
|
|
53
57
|
const bodyId = useCopilotId("cpk-tool-call-group");
|
|
54
58
|
const toggle = () => {
|
|
@@ -64,13 +68,13 @@ const current = computed(() =>
|
|
|
64
68
|
: undefined,
|
|
65
69
|
);
|
|
66
70
|
const preview = computed(() =>
|
|
67
|
-
current.value ?
|
|
71
|
+
current.value ? ɵgetToolCallPreview(current.value) : undefined,
|
|
68
72
|
);
|
|
69
73
|
const done = computed(
|
|
70
74
|
() => props.calls.filter((call) => call.toolMessage).length,
|
|
71
75
|
);
|
|
72
76
|
const statuses = computed(() =>
|
|
73
|
-
props.calls.map((call) =>
|
|
77
|
+
props.calls.map((call) => ɵgetToolCallRowStatus(call, props.isActive)),
|
|
74
78
|
);
|
|
75
79
|
const failedIds = computed(
|
|
76
80
|
() =>
|
|
@@ -80,7 +84,7 @@ const failedIds = computed(
|
|
|
80
84
|
.map((call) => call.toolCall.id),
|
|
81
85
|
),
|
|
82
86
|
);
|
|
83
|
-
const status = computed
|
|
87
|
+
const status = computed<ɵToolCallRowStatus>(() =>
|
|
84
88
|
current.value
|
|
85
89
|
? "running"
|
|
86
90
|
: failedIds.value.size > 0
|
|
@@ -108,10 +112,27 @@ const behind = computed(() =>
|
|
|
108
112
|
open.value ? 0 : Math.min(props.calls.length - 1, 2),
|
|
109
113
|
);
|
|
110
114
|
const latestStatus = computed(() =>
|
|
111
|
-
latest.value ?
|
|
115
|
+
latest.value ? ɵgetToolCallRowStatus(latest.value, props.isActive) : "done",
|
|
112
116
|
);
|
|
113
117
|
const latestPreview = computed(() =>
|
|
114
|
-
latest.value ?
|
|
118
|
+
latest.value ? ɵgetToolCallPreview(latest.value) : undefined,
|
|
119
|
+
);
|
|
120
|
+
const runningLabel = computed(() =>
|
|
121
|
+
current.value
|
|
122
|
+
? ɵformatLabel(labels.value.toolCallRunningLabel, {
|
|
123
|
+
name: current.value.toolCall.function.name,
|
|
124
|
+
})
|
|
125
|
+
: "",
|
|
126
|
+
);
|
|
127
|
+
const usedToolsLabel = computed(() =>
|
|
128
|
+
ɵformatCountLabel(props.calls.length, {
|
|
129
|
+
one: labels.value.toolCallUsedToolsOne,
|
|
130
|
+
other: labels.value.toolCallUsedToolsOther,
|
|
131
|
+
}),
|
|
132
|
+
);
|
|
133
|
+
const toolNames = computed(() => ɵformatToolNames(props.calls));
|
|
134
|
+
const latestStatusLabel = computed(() =>
|
|
135
|
+
toolCallStatusLabel(labels.value, latestStatus.value),
|
|
115
136
|
);
|
|
116
137
|
const layer = "cpk-tool-call-group-stack-layer";
|
|
117
138
|
</script>
|
|
@@ -144,20 +165,18 @@ const layer = "cpk-tool-call-group-stack-layer";
|
|
|
144
165
|
@click="toggle"
|
|
145
166
|
>
|
|
146
167
|
<template v-if="current">
|
|
147
|
-
<span class="cpk-tool-call-group-running cpk-shimmer"
|
|
148
|
-
|
|
149
|
-
>
|
|
168
|
+
<span class="cpk-tool-call-group-running cpk-shimmer">{{
|
|
169
|
+
runningLabel
|
|
170
|
+
}}</span>
|
|
150
171
|
<span v-if="preview" class="cpk-tool-call-group-preview">{{
|
|
151
172
|
preview
|
|
152
173
|
}}</span>
|
|
153
174
|
</template>
|
|
154
175
|
<template v-else>
|
|
155
|
-
<span class="cpk-tool-call-group-line-summary"
|
|
156
|
-
|
|
157
|
-
>
|
|
158
|
-
<span class="cpk-tool-call-group-line-names">{{
|
|
159
|
-
toolNames(calls)
|
|
176
|
+
<span class="cpk-tool-call-group-line-summary">{{
|
|
177
|
+
usedToolsLabel
|
|
160
178
|
}}</span>
|
|
179
|
+
<span class="cpk-tool-call-group-line-names">{{ toolNames }}</span>
|
|
161
180
|
<ToolCallFailedCount :calls="calls" />
|
|
162
181
|
</template>
|
|
163
182
|
<ToolCallChevron :open="open" />
|
|
@@ -206,10 +225,15 @@ const layer = "cpk-tool-call-group-stack-layer";
|
|
|
206
225
|
@click="toggle"
|
|
207
226
|
>
|
|
208
227
|
<template v-if="open">
|
|
209
|
-
{{
|
|
228
|
+
{{
|
|
229
|
+
ɵformatCountLabel(calls.length, {
|
|
230
|
+
one: labels.toolCallToolCallCountOne,
|
|
231
|
+
other: labels.toolCallToolCallCountOther,
|
|
232
|
+
})
|
|
233
|
+
}}
|
|
210
234
|
<ToolCallFailedCount :calls="calls" />
|
|
211
235
|
<span class="cpk-tool-call-group-stack-collapse">
|
|
212
|
-
|
|
236
|
+
{{ labels.toolCallCollapseLabel }}
|
|
213
237
|
<ToolCallChevron
|
|
214
238
|
:open="true"
|
|
215
239
|
class="cpk-tool-call-group-stack-collapse-icon"
|
|
@@ -236,13 +260,16 @@ const layer = "cpk-tool-call-group-stack-layer";
|
|
|
236
260
|
>
|
|
237
261
|
<!-- The status icon is decorative, so say the status. -->
|
|
238
262
|
<span class="cpk-tool-call-group-stack-status">{{
|
|
239
|
-
|
|
263
|
+
latestStatusLabel
|
|
240
264
|
}}</span>
|
|
241
265
|
</span>
|
|
242
266
|
<span class="cpk-tool-call-group-stack-meta">
|
|
243
267
|
<ToolCallFailedCount :calls="calls" />
|
|
244
268
|
<span class="cpk-tool-call-group-stack-count">{{
|
|
245
|
-
|
|
269
|
+
ɵformatCountLabel(calls.length, {
|
|
270
|
+
one: labels.toolCallCallCountOne,
|
|
271
|
+
other: labels.toolCallCallCountOther,
|
|
272
|
+
})
|
|
246
273
|
}}</span>
|
|
247
274
|
<ToolCallChevron
|
|
248
275
|
:open="false"
|
|
@@ -255,9 +282,7 @@ const layer = "cpk-tool-call-group-stack-layer";
|
|
|
255
282
|
call change ("read_file: Running", then "read_file: Done"); the
|
|
256
283
|
button only names it. -->
|
|
257
284
|
<span aria-live="polite" class="cpk-tool-call-group-stack-live">{{
|
|
258
|
-
open
|
|
259
|
-
? ""
|
|
260
|
-
: `${latest.toolCall.function.name}: ${statusLabels[latestStatus]}`
|
|
285
|
+
open ? "" : `${latest.toolCall.function.name}: ${latestStatusLabel}`
|
|
261
286
|
}}</span>
|
|
262
287
|
</div>
|
|
263
288
|
<!-- Each call gets the collapsed stack's card, easing out of the stack. -->
|
|
@@ -292,28 +317,26 @@ const layer = "cpk-tool-call-group-stack-layer";
|
|
|
292
317
|
>
|
|
293
318
|
<ToolCallStatusIcon :status="status" />
|
|
294
319
|
<template v-if="current">
|
|
295
|
-
<span class="cpk-tool-call-group-running cpk-shimmer"
|
|
296
|
-
|
|
297
|
-
>
|
|
320
|
+
<span class="cpk-tool-call-group-running cpk-shimmer">{{
|
|
321
|
+
runningLabel
|
|
322
|
+
}}</span>
|
|
298
323
|
<span v-if="preview" class="cpk-tool-call-group-preview">{{
|
|
299
324
|
preview
|
|
300
325
|
}}</span>
|
|
301
326
|
</template>
|
|
302
327
|
<template v-else>
|
|
303
|
-
<span class="cpk-tool-call-group-card-summary"
|
|
304
|
-
|
|
305
|
-
>
|
|
306
|
-
<span class="cpk-tool-call-group-card-names">{{
|
|
307
|
-
toolNames(calls)
|
|
328
|
+
<span class="cpk-tool-call-group-card-summary">{{
|
|
329
|
+
usedToolsLabel
|
|
308
330
|
}}</span>
|
|
331
|
+
<span class="cpk-tool-call-group-card-names">{{ toolNames }}</span>
|
|
309
332
|
</template>
|
|
310
333
|
<span class="cpk-tool-call-group-card-meta">
|
|
311
334
|
<ToolCallFailedCount v-if="status === 'failed'" :calls="calls" />
|
|
312
335
|
<span v-else class="cpk-tool-call-group-card-status">{{
|
|
313
336
|
status !== "running"
|
|
314
|
-
?
|
|
337
|
+
? toolCallStatusLabel(labels, status)
|
|
315
338
|
: done > 0
|
|
316
|
-
?
|
|
339
|
+
? ɵformatLabel(labels.toolCallDoneCountLabel, { count: done })
|
|
317
340
|
: ""
|
|
318
341
|
}}</span>
|
|
319
342
|
<ToolCallChevron :open="open" />
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { Message, ToolCall } from "@ag-ui/core";
|
|
3
3
|
import { DEFAULT_AGENT_ID } from "@copilotkit/shared";
|
|
4
|
+
import { ɵresolveToolCallRenderer } from "@copilotkit/core";
|
|
4
5
|
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
5
6
|
import { useCopilotChatConfiguration } from "../../providers/useCopilotChatConfiguration";
|
|
6
7
|
import type { CopilotChatToolCallRenderSlotProps } from "./types";
|
|
7
8
|
import {
|
|
8
|
-
getCoreRenderConfig,
|
|
9
9
|
getCoreRenderProps,
|
|
10
10
|
getToolCallMemoDeps,
|
|
11
11
|
getToolCallRenderProps,
|
|
@@ -55,9 +55,9 @@ function getCoreProps() {
|
|
|
55
55
|
|
|
56
56
|
function getRenderConfig() {
|
|
57
57
|
const agentId = config.value?.agentId ?? DEFAULT_AGENT_ID;
|
|
58
|
-
return
|
|
59
|
-
props.toolCall,
|
|
58
|
+
return ɵresolveToolCallRenderer(
|
|
60
59
|
copilotkit.value.renderToolCalls,
|
|
60
|
+
props.toolCall.function.name,
|
|
61
61
|
agentId,
|
|
62
62
|
);
|
|
63
63
|
}
|
|
@@ -3,6 +3,14 @@ import { computed, defineComponent, h, inject, provide, useSlots } from "vue";
|
|
|
3
3
|
import type { PropType } from "vue";
|
|
4
4
|
import type { Slots, VNode } from "vue";
|
|
5
5
|
import type { AssistantMessage, Message } from "@ag-ui/core";
|
|
6
|
+
import {
|
|
7
|
+
ɵgetToolCallLayouts,
|
|
8
|
+
ɵgetToolCallRendererNames,
|
|
9
|
+
} from "@copilotkit/core";
|
|
10
|
+
import type {
|
|
11
|
+
CopilotChatToolCallDisplay,
|
|
12
|
+
ToolCallEntry,
|
|
13
|
+
} from "@copilotkit/core";
|
|
6
14
|
import { useCopilotKit } from "../../providers/useCopilotKit";
|
|
7
15
|
import type {
|
|
8
16
|
CopilotChatToolCallGroupAppearance,
|
|
@@ -17,14 +25,6 @@ import {
|
|
|
17
25
|
ToolCallGroupContextKey,
|
|
18
26
|
} from "./tool-call-display-context";
|
|
19
27
|
import type { ToolCallGroupContextValue } from "./tool-call-display-context";
|
|
20
|
-
import {
|
|
21
|
-
getToolCallLayouts,
|
|
22
|
-
getToolCallRendererNames,
|
|
23
|
-
} from "./tool-call-layout";
|
|
24
|
-
import type {
|
|
25
|
-
CopilotChatToolCallDisplay,
|
|
26
|
-
ToolCallEntry,
|
|
27
|
-
} from "./tool-call-layout";
|
|
28
28
|
|
|
29
29
|
const props = withDefaults(
|
|
30
30
|
defineProps<{
|
|
@@ -84,13 +84,15 @@ const layout = computed(() => {
|
|
|
84
84
|
if (display.value === "separate") return undefined;
|
|
85
85
|
const viewLayout = context?.value.layouts.get(props.message.id);
|
|
86
86
|
if (viewLayout) return viewLayout;
|
|
87
|
-
const rendererNames =
|
|
87
|
+
const rendererNames = ɵgetToolCallRendererNames(
|
|
88
88
|
copilotkit.value.renderToolCalls,
|
|
89
|
-
getToolCallSlotNames(),
|
|
90
|
-
);
|
|
91
|
-
return getToolCallLayouts([props.message], props.messages, rendererNames).get(
|
|
92
|
-
props.message.id,
|
|
89
|
+
{ slotNames: getToolCallSlotNames() },
|
|
93
90
|
);
|
|
91
|
+
return ɵgetToolCallLayouts(
|
|
92
|
+
[props.message],
|
|
93
|
+
props.messages,
|
|
94
|
+
rendererNames,
|
|
95
|
+
).get(props.message.id);
|
|
94
96
|
});
|
|
95
97
|
|
|
96
98
|
// Whether the agent may still finish a trailing group's calls. Without a
|
|
@@ -11,8 +11,7 @@ import {
|
|
|
11
11
|
import type { Message } from "@ag-ui/core";
|
|
12
12
|
import type { Suggestion } from "@copilotkit/core";
|
|
13
13
|
import type { Attachment } from "@copilotkit/shared";
|
|
14
|
-
import {
|
|
15
|
-
import { CopilotChatDefaultLabels } from "../../providers/types";
|
|
14
|
+
import { useChatLabels } from "./use-chat-labels";
|
|
16
15
|
import { useKeyboardHeight } from "../../hooks/use-keyboard-height";
|
|
17
16
|
import { usePinToSend } from "../../hooks/use-pin-to-send";
|
|
18
17
|
import { IconChevronDown, IconUpload } from "../icons";
|
|
@@ -127,8 +126,7 @@ const emit = defineEmits<{
|
|
|
127
126
|
"finish-transcribe": [];
|
|
128
127
|
}>();
|
|
129
128
|
|
|
130
|
-
const
|
|
131
|
-
const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
|
|
129
|
+
const labels = useChatLabels();
|
|
132
130
|
const componentSlots = useSlots();
|
|
133
131
|
|
|
134
132
|
const scrollContainerRef = ref<HTMLElement | null>(null);
|
|
@@ -457,7 +455,9 @@ onBeforeUnmount(() => {
|
|
|
457
455
|
>
|
|
458
456
|
<div class="cpk-chat-view-drop-overlay-content">
|
|
459
457
|
<IconUpload class="cpk-chat-view-drop-overlay-icon" />
|
|
460
|
-
<span class="cpk-chat-view-drop-overlay-label">
|
|
458
|
+
<span class="cpk-chat-view-drop-overlay-label">{{
|
|
459
|
+
labels.chatDropFilesLabel
|
|
460
|
+
}}</span>
|
|
461
461
|
</div>
|
|
462
462
|
</div>
|
|
463
463
|
<slot
|
|
@@ -5,10 +5,15 @@
|
|
|
5
5
|
* for 9s · 7 tools" and toggles the work it folded away.
|
|
6
6
|
*/
|
|
7
7
|
import { computed, ref, watch } from "vue";
|
|
8
|
+
import {
|
|
9
|
+
ɵcountFailedToolCalls,
|
|
10
|
+
ɵformatLabel,
|
|
11
|
+
ɵformatWorkDuration,
|
|
12
|
+
ɵformatCountLabel,
|
|
13
|
+
} from "@copilotkit/core";
|
|
8
14
|
import { IconChevronRight } from "../icons";
|
|
9
15
|
import type { CopilotChatWorkSummarySlotProps } from "./types";
|
|
10
|
-
import {
|
|
11
|
-
import { formatDuration } from "./turn-work";
|
|
16
|
+
import { useChatLabels } from "./use-chat-labels";
|
|
12
17
|
|
|
13
18
|
// `onClick` falls through to the button.
|
|
14
19
|
const props = defineProps<Omit<CopilotChatWorkSummarySlotProps, "onClick">>();
|
|
@@ -28,9 +33,8 @@ watch(
|
|
|
28
33
|
{ immediate: true },
|
|
29
34
|
);
|
|
30
35
|
|
|
31
|
-
const
|
|
32
|
-
|
|
33
|
-
);
|
|
36
|
+
const labels = useChatLabels();
|
|
37
|
+
const failed = computed(() => ɵcountFailedToolCalls(props.calls));
|
|
34
38
|
const liveMs = computed(() =>
|
|
35
39
|
props.elapsedMs !== undefined && props.workingSince !== undefined
|
|
36
40
|
? props.elapsedMs + Math.max(0, now.value - props.workingSince)
|
|
@@ -39,9 +43,33 @@ const liveMs = computed(() =>
|
|
|
39
43
|
// A finished reply worked for at least a second.
|
|
40
44
|
const duration = computed(() =>
|
|
41
45
|
props.elapsedMs !== undefined
|
|
42
|
-
?
|
|
46
|
+
? ɵformatWorkDuration(Math.max(1000, props.elapsedMs))
|
|
43
47
|
: undefined,
|
|
44
48
|
);
|
|
49
|
+
const toolCount = computed(() =>
|
|
50
|
+
ɵformatCountLabel(props.calls.length, {
|
|
51
|
+
one: labels.value.toolCallToolCountOne,
|
|
52
|
+
other: labels.value.toolCallToolCountOther,
|
|
53
|
+
}),
|
|
54
|
+
);
|
|
55
|
+
const doneLabel = computed(() =>
|
|
56
|
+
duration.value
|
|
57
|
+
? ɵformatLabel(labels.value.workSummaryWorkedForLabel, {
|
|
58
|
+
duration: duration.value,
|
|
59
|
+
})
|
|
60
|
+
: ɵformatCountLabel(props.calls.length, {
|
|
61
|
+
one: labels.value.toolCallUsedToolsOne,
|
|
62
|
+
other: labels.value.toolCallUsedToolsOther,
|
|
63
|
+
}),
|
|
64
|
+
);
|
|
65
|
+
const liveDuration = computed(() =>
|
|
66
|
+
liveMs.value !== undefined ? ɵformatWorkDuration(liveMs.value) : undefined,
|
|
67
|
+
);
|
|
68
|
+
const failedLabel = computed(() =>
|
|
69
|
+
ɵformatLabel(labels.value.toolCallFailedCountLabel, {
|
|
70
|
+
count: failed.value,
|
|
71
|
+
}),
|
|
72
|
+
);
|
|
45
73
|
</script>
|
|
46
74
|
|
|
47
75
|
<template>
|
|
@@ -54,25 +82,23 @@ const duration = computed(() =>
|
|
|
54
82
|
class="cpk-work-summary"
|
|
55
83
|
>
|
|
56
84
|
<template v-if="isWorking">
|
|
57
|
-
<span class="cpk-work-summary-label cpk-shimmer">
|
|
85
|
+
<span class="cpk-work-summary-label cpk-shimmer">{{
|
|
86
|
+
labels.workSummaryWorkingLabel
|
|
87
|
+
}}</span>
|
|
58
88
|
<span
|
|
59
|
-
v-if="
|
|
89
|
+
v-if="liveDuration !== undefined"
|
|
60
90
|
class="cpk-work-summary-detail cpk-work-summary-timer"
|
|
61
|
-
>{{
|
|
91
|
+
>{{ liveDuration }}</span
|
|
62
92
|
>
|
|
63
93
|
</template>
|
|
64
94
|
<template v-else>
|
|
65
|
-
<span class="cpk-work-summary-label">{{
|
|
66
|
-
duration
|
|
67
|
-
? `Worked for ${duration}`
|
|
68
|
-
: `Used ${pluralize(calls.length, "tool")}`
|
|
69
|
-
}}</span>
|
|
95
|
+
<span class="cpk-work-summary-label">{{ doneLabel }}</span>
|
|
70
96
|
<span v-if="duration" class="cpk-work-summary-detail">{{
|
|
71
|
-
|
|
97
|
+
toolCount
|
|
98
|
+
}}</span>
|
|
99
|
+
<span v-if="failed > 0" class="cpk-work-summary-failed">{{
|
|
100
|
+
failedLabel
|
|
72
101
|
}}</span>
|
|
73
|
-
<span v-if="failed > 0" class="cpk-work-summary-failed"
|
|
74
|
-
>{{ failed }} failed</span
|
|
75
|
-
>
|
|
76
102
|
</template>
|
|
77
103
|
<IconChevronRight
|
|
78
104
|
aria-hidden="true"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
2
2
|
import { defineComponent, nextTick, onMounted } from "vue";
|
|
3
3
|
import { fireEvent, render, screen } from "@testing-library/vue";
|
|
4
|
-
import type {
|
|
4
|
+
import type { ReasoningMessage } from "@ag-ui/core";
|
|
5
5
|
import type { Attachment } from "@copilotkit/shared";
|
|
6
6
|
import CopilotKitProvider from "../../../providers/CopilotKitProvider.vue";
|
|
7
7
|
import CopilotChatConfigurationProvider from "../../../providers/CopilotChatConfigurationProvider.vue";
|
|
@@ -16,6 +16,8 @@ import { CopilotModalHeader, CopilotSidebarView } from "../index";
|
|
|
16
16
|
// hard-coded English.
|
|
17
17
|
const germanLabels: Partial<Record<keyof CopilotChatLabels, string>> = {
|
|
18
18
|
reasoningMessageThinkingLabel: "Denkt nach…",
|
|
19
|
+
reasoningMessageThoughtForLabel: "Gedacht für {duration}",
|
|
20
|
+
reasoningMessageDurationFewSeconds: "ein paar Sekunden",
|
|
19
21
|
chatInputSlashMenuLabel: "Befehle",
|
|
20
22
|
chatInputSlashMenuEmptyText: "Keine Befehle gefunden",
|
|
21
23
|
attachmentRemoveButtonLabel: "Anhang entfernen",
|
|
@@ -26,11 +28,11 @@ const germanLabels: Partial<Record<keyof CopilotChatLabels, string>> = {
|
|
|
26
28
|
sidebarLabel: "Chat-Seitenleiste",
|
|
27
29
|
};
|
|
28
30
|
|
|
29
|
-
const reasoning = {
|
|
31
|
+
const reasoning: ReasoningMessage = {
|
|
30
32
|
id: "reasoning-1",
|
|
31
33
|
role: "reasoning",
|
|
32
34
|
content: "",
|
|
33
|
-
}
|
|
35
|
+
};
|
|
34
36
|
|
|
35
37
|
const video: Attachment = {
|
|
36
38
|
id: "clip",
|
|
@@ -66,7 +68,7 @@ function renderWithLabels(template: string) {
|
|
|
66
68
|
return {
|
|
67
69
|
labels: germanLabels,
|
|
68
70
|
reasoning,
|
|
69
|
-
reasoningMessages: [reasoning]
|
|
71
|
+
reasoningMessages: [reasoning],
|
|
70
72
|
attachments: [video],
|
|
71
73
|
toolsMenu: [{ label: "Say hi", action: vi.fn() }],
|
|
72
74
|
};
|
|
@@ -112,6 +114,19 @@ describe("chat strings from labels", () => {
|
|
|
112
114
|
expect(screen.queryByText("Thinking…")).toBeNull();
|
|
113
115
|
});
|
|
114
116
|
|
|
117
|
+
it("uses the configured duration labels once the model is done", () => {
|
|
118
|
+
renderWithLabels(`
|
|
119
|
+
<CopilotChatReasoningMessage
|
|
120
|
+
:message="reasoning"
|
|
121
|
+
:messages="reasoningMessages"
|
|
122
|
+
:is-running="false"
|
|
123
|
+
/>
|
|
124
|
+
`);
|
|
125
|
+
|
|
126
|
+
expect(screen.getByText("Gedacht für ein paar Sekunden")).toBeDefined();
|
|
127
|
+
expect(screen.queryByText(/Thought for/)).toBeNull();
|
|
128
|
+
});
|
|
129
|
+
|
|
115
130
|
it("passes the elapsed reasoning time to a custom header", async () => {
|
|
116
131
|
vi.useFakeTimers();
|
|
117
132
|
renderWithLabels(`
|
|
@@ -559,6 +559,38 @@ describe("CopilotChatInput", () => {
|
|
|
559
559
|
expect(screen.getByRole("button", { name: "Stop" })).toBe(getSendButton());
|
|
560
560
|
});
|
|
561
561
|
|
|
562
|
+
describe("Enter while the agent runs", () => {
|
|
563
|
+
async function pressEnterWhileRunning(modelValue: string) {
|
|
564
|
+
const onStop = vi.fn();
|
|
565
|
+
renderWithProvider({
|
|
566
|
+
props: { modelValue, isRunning: true },
|
|
567
|
+
listeners: { onSubmitMessage: mockOnSubmitMessage, onStop },
|
|
568
|
+
});
|
|
569
|
+
await fireEvent.keyDown(
|
|
570
|
+
screen.getByPlaceholderText("Type a message..."),
|
|
571
|
+
{
|
|
572
|
+
key: "Enter",
|
|
573
|
+
shiftKey: false,
|
|
574
|
+
},
|
|
575
|
+
);
|
|
576
|
+
return onStop;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
it("sends the typed text and does not stop the run", async () => {
|
|
580
|
+
const onStop = await pressEnterWhileRunning(" next question ");
|
|
581
|
+
|
|
582
|
+
expect(mockOnSubmitMessage).toHaveBeenCalledWith("next question");
|
|
583
|
+
expect(onStop).not.toHaveBeenCalled();
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
it("stops the run when the input is empty", async () => {
|
|
587
|
+
const onStop = await pressEnterWhileRunning("");
|
|
588
|
+
|
|
589
|
+
expect(onStop).toHaveBeenCalledOnce();
|
|
590
|
+
expect(mockOnSubmitMessage).not.toHaveBeenCalled();
|
|
591
|
+
});
|
|
592
|
+
});
|
|
593
|
+
|
|
562
594
|
it("names the send button with the configured labels", () => {
|
|
563
595
|
renderWithProvider({
|
|
564
596
|
template: `
|
|
@@ -799,7 +831,7 @@ describe("CopilotChatInput", () => {
|
|
|
799
831
|
|
|
800
832
|
await fireEvent.click(addButton);
|
|
801
833
|
const menuItem = await screen.findByRole("menuitem", {
|
|
802
|
-
name: "Add
|
|
834
|
+
name: "Add attachments",
|
|
803
835
|
});
|
|
804
836
|
await fireEvent.click(menuItem);
|
|
805
837
|
expect(handleAddFile).toHaveBeenCalledTimes(1);
|