@copilotkit/vue 1.72.1-canary.sp-longthread-perf → 1.73.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.
Files changed (61) hide show
  1. package/PARITY.md +15 -1
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.mjs +2 -2
  4. package/dist/use-render-activity-message-C45MYgwB.cjs +85 -0
  5. package/dist/use-render-activity-message-C45MYgwB.cjs.map +1 -0
  6. package/dist/use-render-activity-message-DI4kGqHF.js +9758 -0
  7. package/dist/use-render-activity-message-DI4kGqHF.js.map +1 -0
  8. package/dist/v2/components/LicenseWarningBanner.vue.d.ts +3 -5
  9. package/dist/v2/components/LicenseWarningBanner.vue.d.ts.map +1 -1
  10. package/dist/v2/components/chat/CopilotChat.vue.d.ts.map +1 -1
  11. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts +4 -0
  12. package/dist/v2/components/chat/CopilotChatAssistantMessage.vue.d.ts.map +1 -1
  13. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts +7 -0
  14. package/dist/v2/components/chat/CopilotChatInput.vue.d.ts.map +1 -1
  15. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts +2 -0
  16. package/dist/v2/components/chat/CopilotChatUserMessage.vue.d.ts.map +1 -1
  17. package/dist/v2/components/chat/CopilotChatView.vue.d.ts +8 -2
  18. package/dist/v2/components/chat/CopilotChatView.vue.d.ts.map +1 -1
  19. package/dist/v2/components/chat/CopilotPopup.vue.d.ts.map +1 -1
  20. package/dist/v2/components/chat/CopilotPopupView.vue.d.ts.map +1 -1
  21. package/dist/v2/components/chat/CopilotPopupViewInternal.vue.d.ts.map +1 -1
  22. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts +7 -4
  23. package/dist/v2/components/chat/CopilotPopupWelcomeScreen.vue.d.ts.map +1 -1
  24. package/dist/v2/components/chat/CopilotSidebar.vue.d.ts.map +1 -1
  25. package/dist/v2/components/chat/CopilotSidebarView.vue.d.ts.map +1 -1
  26. package/dist/v2/components/chat/CopilotSidebarViewInternal.vue.d.ts.map +1 -1
  27. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts +8 -5
  28. package/dist/v2/components/chat/CopilotSidebarWelcomeScreen.vue.d.ts.map +1 -1
  29. package/dist/v2/components/chat/index.d.ts +50 -26
  30. package/dist/v2/components/chat/index.d.ts.map +1 -1
  31. package/dist/v2/components/chat/types.d.ts +44 -17
  32. package/dist/v2/components/chat/types.d.ts.map +1 -1
  33. package/dist/v2/index.cjs +1 -1
  34. package/dist/v2/index.mjs +1 -1
  35. package/package.json +6 -6
  36. package/src/v2/components/LicenseWarningBanner.vue +5 -17
  37. package/src/v2/components/__tests__/LicenseWarningBanner.test.ts +23 -0
  38. package/src/v2/components/chat/CopilotChat.vue +21 -14
  39. package/src/v2/components/chat/CopilotChatAssistantMessage.vue +12 -21
  40. package/src/v2/components/chat/CopilotChatInput.vue +32 -26
  41. package/src/v2/components/chat/CopilotChatUserMessage.vue +19 -19
  42. package/src/v2/components/chat/CopilotChatView.vue +31 -39
  43. package/src/v2/components/chat/CopilotPopup.vue +8 -10
  44. package/src/v2/components/chat/CopilotPopupView.vue +8 -18
  45. package/src/v2/components/chat/CopilotPopupViewInternal.vue +5 -19
  46. package/src/v2/components/chat/CopilotPopupWelcomeScreen.vue +36 -6
  47. package/src/v2/components/chat/CopilotSidebar.vue +8 -10
  48. package/src/v2/components/chat/CopilotSidebarView.vue +8 -18
  49. package/src/v2/components/chat/CopilotSidebarViewInternal.vue +5 -19
  50. package/src/v2/components/chat/CopilotSidebarWelcomeScreen.vue +36 -6
  51. package/src/v2/components/chat/__tests__/CopilotChat.e2e.test.ts +156 -5
  52. package/src/v2/components/chat/__tests__/CopilotChatInput.test.ts +34 -0
  53. package/src/v2/components/chat/__tests__/CopilotChatUserMessage.test.ts +46 -0
  54. package/src/v2/components/chat/__tests__/CopilotChatView.test.ts +118 -0
  55. package/src/v2/components/chat/__tests__/CopilotPopupView.test.ts +79 -0
  56. package/src/v2/components/chat/__tests__/CopilotSidebarView.test.ts +93 -0
  57. package/src/v2/components/chat/types.ts +73 -18
  58. package/dist/use-render-activity-message-Ciee03Rx.js +0 -9702
  59. package/dist/use-render-activity-message-Ciee03Rx.js.map +0 -1
  60. package/dist/use-render-activity-message-DXJDZGkW.cjs +0 -85
  61. package/dist/use-render-activity-message-DXJDZGkW.cjs.map +0 -1
@@ -1,7 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import {
3
3
  computed,
4
- getCurrentInstance,
5
4
  nextTick,
6
5
  onBeforeUnmount,
7
6
  onMounted,
@@ -74,9 +73,12 @@ defineSlots<{
74
73
  inputMode: CopilotChatInputMode;
75
74
  inputToolsMenu: (ToolsMenuItem | "-")[];
76
75
  attachments: Attachment[];
76
+ canStop: boolean;
77
+ canAddFile: boolean;
78
+ canTranscribe: boolean;
77
79
  onUpdateModelValue: (value: string) => void;
78
80
  onSubmitMessage: (value: string) => void;
79
- onStop?: () => void;
81
+ onStop: () => void;
80
82
  onAddFile: () => void;
81
83
  onStartTranscribe: () => void;
82
84
  onCancelTranscribe: () => void;
@@ -96,9 +98,12 @@ defineSlots<{
96
98
  isRunning: boolean;
97
99
  inputMode: CopilotChatInputMode;
98
100
  inputToolsMenu: (ToolsMenuItem | "-")[];
101
+ canStop: boolean;
102
+ canAddFile: boolean;
103
+ canTranscribe: boolean;
99
104
  onUpdateModelValue: (value: string) => void;
100
105
  onSubmitMessage: (value: string) => void;
101
- onStop?: () => void;
106
+ onStop: () => void;
102
107
  onAddFile: () => void;
103
108
  onStartTranscribe: () => void;
104
109
  onCancelTranscribe: () => void;
@@ -123,7 +128,6 @@ const emit = defineEmits<{
123
128
 
124
129
  const config = useCopilotChatConfiguration();
125
130
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
126
- const instance = getCurrentInstance();
127
131
  const componentSlots = useSlots();
128
132
 
129
133
  const scrollContainerRef = ref<HTMLElement | null>(null);
@@ -174,9 +178,6 @@ const hasSuggestions = computed(
174
178
  const hasAttachments = computed(
175
179
  () => Array.isArray(props.attachments) && props.attachments.length > 0,
176
180
  );
177
- const vnodeProps = computed(
178
- () => (instance?.vnode.props ?? {}) as Record<string, unknown>,
179
- );
180
181
  const forwardedMessageViewSlotNames = computed(() =>
181
182
  Object.keys(componentSlots).filter(
182
183
  (slotName) =>
@@ -197,20 +198,6 @@ const shouldShowWelcomeScreen = computed(
197
198
  !props.isConnecting &&
198
199
  !props.hasExplicitThreadId,
199
200
  );
200
- const hasAddFileAction = computed(() => hasListener("onAddFile"));
201
- const hasStopAction = computed(() => hasListener("onStop"));
202
- const hasStartTranscribeAction = computed(() =>
203
- hasListener("onStartTranscribe"),
204
- );
205
- const hasCancelTranscribeAction = computed(() =>
206
- hasListener("onCancelTranscribe"),
207
- );
208
- const hasFinishTranscribeAction = computed(() =>
209
- hasListener("onFinishTranscribe"),
210
- );
211
- const hasFinishTranscribeWithAudioAction = computed(
212
- () => typeof props.onFinishTranscribeWithAudio === "function",
213
- );
214
201
  // Mirrors React: `paddingBottom = inputContainerHeight + (hasSuggestions ? 4 : 32)`.
215
202
  // React intentionally does NOT add bonus padding for attachments — the
216
203
  // attachment queue lives inside the input overlay, so its height is already
@@ -343,14 +330,6 @@ function handleScroll() {
343
330
  updateIsAtBottom();
344
331
  }
345
332
 
346
- function hasListener(listenerName: string) {
347
- const listener = vnodeProps.value[listenerName];
348
- if (Array.isArray(listener)) {
349
- return listener.length > 0;
350
- }
351
- return !!listener;
352
- }
353
-
354
333
  function handleInputValueChange(value: string) {
355
334
  if (!isControlledInput.value) {
356
335
  localInputValue.value = value;
@@ -405,31 +384,35 @@ async function handleFinishTranscribeWithAudio(audioBlob: Blob) {
405
384
  const inputEventProps = computed(() => {
406
385
  const listeners: Record<string, unknown> = {
407
386
  "onUpdate:modelValue": handleInputValueChange,
408
- onSubmitMessage: handleSubmitMessage,
387
+ onSubmitMessage: props.onSubmitMessage ? handleSubmitMessage : undefined,
409
388
  };
410
389
 
411
- if (hasStopAction.value) {
390
+ if (props.onStop) {
412
391
  listeners.onStop = handleStop;
413
392
  }
414
- if (hasAddFileAction.value) {
393
+ if (props.onAddFile) {
415
394
  listeners.onAddFile = handleAddFile;
416
395
  }
417
- if (hasStartTranscribeAction.value) {
396
+ if (props.onStartTranscribe) {
418
397
  listeners.onStartTranscribe = handleStartTranscribe;
419
398
  }
420
- if (hasCancelTranscribeAction.value) {
399
+ if (props.onCancelTranscribe) {
421
400
  listeners.onCancelTranscribe = handleCancelTranscribe;
422
401
  }
423
- if (hasFinishTranscribeAction.value) {
402
+ if (props.onFinishTranscribe) {
424
403
  listeners.onFinishTranscribe = handleFinishTranscribe;
425
404
  }
426
- if (hasFinishTranscribeWithAudioAction.value) {
405
+ if (props.onFinishTranscribeWithAudio) {
427
406
  listeners.onFinishTranscribeWithAudio = handleFinishTranscribeWithAudio;
428
407
  }
429
408
 
430
409
  return listeners;
431
410
  });
432
411
 
412
+ const canStop = computed(() => !!props.onStop);
413
+ const canAddFile = computed(() => !!props.onAddFile);
414
+ const canTranscribe = computed(() => !!props.onStartTranscribe);
415
+
433
416
  onMounted(async () => {
434
417
  await nextTick();
435
418
  syncInputContainerHeight();
@@ -484,9 +467,12 @@ onBeforeUnmount(() => {
484
467
  :is-running="isRunning"
485
468
  :input-mode="inputMode"
486
469
  :input-tools-menu="inputToolsMenu"
470
+ :can-stop="canStop"
471
+ :can-add-file="canAddFile"
472
+ :can-transcribe="canTranscribe"
487
473
  :on-update-model-value="handleInputValueChange"
488
474
  :on-submit-message="handleSubmitMessage"
489
- :on-stop="hasStopAction ? handleStop : undefined"
475
+ :on-stop="handleStop"
490
476
  :on-add-file="handleAddFile"
491
477
  :on-start-transcribe="handleStartTranscribe"
492
478
  :on-cancel-transcribe="handleCancelTranscribe"
@@ -527,9 +513,12 @@ onBeforeUnmount(() => {
527
513
  :input-mode="inputMode"
528
514
  :input-tools-menu="inputToolsMenu"
529
515
  :attachments="attachments ?? []"
516
+ :can-stop="canStop"
517
+ :can-add-file="canAddFile"
518
+ :can-transcribe="canTranscribe"
530
519
  :on-update-model-value="handleInputValueChange"
531
520
  :on-submit-message="handleSubmitMessage"
532
- :on-stop="hasStopAction ? handleStop : undefined"
521
+ :on-stop="handleStop"
533
522
  :on-add-file="handleAddFile"
534
523
  :on-start-transcribe="handleStartTranscribe"
535
524
  :on-cancel-transcribe="handleCancelTranscribe"
@@ -713,9 +702,12 @@ onBeforeUnmount(() => {
713
702
  :input-mode="inputMode"
714
703
  :input-tools-menu="inputToolsMenu"
715
704
  :attachments="attachments ?? []"
705
+ :can-stop="canStop"
706
+ :can-add-file="canAddFile"
707
+ :can-transcribe="canTranscribe"
716
708
  :on-update-model-value="handleInputValueChange"
717
709
  :on-submit-message="handleSubmitMessage"
718
- :on-stop="hasStopAction ? handleStop : undefined"
710
+ :on-stop="handleStop"
719
711
  :on-add-file="handleAddFile"
720
712
  :on-start-transcribe="handleStartTranscribe"
721
713
  :on-cancel-transcribe="handleCancelTranscribe"
@@ -22,16 +22,14 @@ function popupViewEventBindings(slotProps: CopilotChatViewOverrideSlotProps) {
22
22
  onSubmitMessage: slotProps.onSubmitMessage,
23
23
  onInputChange: slotProps.onInputChange,
24
24
  onSelectSuggestion: slotProps.onSelectSuggestion,
25
- ...(slotProps.onStop ? { onStop: slotProps.onStop } : {}),
26
- ...(slotProps.onAddFile ? { onAddFile: slotProps.onAddFile } : {}),
27
- ...(slotProps.onStartTranscribe
28
- ? { onStartTranscribe: slotProps.onStartTranscribe }
29
- : {}),
30
- ...(slotProps.onCancelTranscribe
31
- ? { onCancelTranscribe: slotProps.onCancelTranscribe }
32
- : {}),
33
- ...(slotProps.onFinishTranscribe
34
- ? { onFinishTranscribe: slotProps.onFinishTranscribe }
25
+ ...(slotProps.canStop ? { onStop: slotProps.onStop } : {}),
26
+ ...(slotProps.canAddFile ? { onAddFile: slotProps.onAddFile } : {}),
27
+ ...(slotProps.canTranscribe
28
+ ? {
29
+ onStartTranscribe: slotProps.onStartTranscribe,
30
+ onCancelTranscribe: slotProps.onCancelTranscribe,
31
+ onFinishTranscribe: slotProps.onFinishTranscribe,
32
+ }
35
33
  : {}),
36
34
  };
37
35
  }
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, getCurrentInstance, useAttrs } from "vue";
2
+ import { computed, useAttrs } from "vue";
3
3
  import CopilotChatConfigurationProvider from "../../providers/CopilotChatConfigurationProvider.vue";
4
4
  import CopilotPopupViewInternal from "./CopilotPopupViewInternal.vue";
5
5
  import type {
@@ -66,18 +66,6 @@ const emit = defineEmits<{
66
66
  }>();
67
67
 
68
68
  const attrs = useAttrs();
69
- const instance = getCurrentInstance();
70
- const vnodeProps = computed(
71
- () => (instance?.vnode.props ?? {}) as Record<string, unknown>,
72
- );
73
-
74
- function hasListener(listenerName: string) {
75
- const listener = vnodeProps.value[listenerName];
76
- if (Array.isArray(listener)) {
77
- return listener.length > 0;
78
- }
79
- return !!listener;
80
- }
81
69
 
82
70
  const internalProps = computed(() => {
83
71
  const { defaultOpen: _defaultOpen, ...rest } = props;
@@ -87,7 +75,6 @@ const internalProps = computed(() => {
87
75
  const forwardedEventListeners = computed(() => {
88
76
  const listeners: Record<string, unknown> = {
89
77
  onSubmitMessage: (value: string) => emit("submit-message", value),
90
- onStop: () => emit("stop"),
91
78
  onInputChange: (value: string) => emit("input-change", value),
92
79
  onSelectSuggestion: (
93
80
  suggestion: (typeof props.suggestions)[number],
@@ -95,16 +82,19 @@ const forwardedEventListeners = computed(() => {
95
82
  ) => emit("select-suggestion", suggestion, index),
96
83
  };
97
84
 
98
- if (hasListener("onAddFile")) {
85
+ if (props.onStop) {
86
+ listeners.onStop = () => emit("stop");
87
+ }
88
+ if (props.onAddFile) {
99
89
  listeners.onAddFile = () => emit("add-file");
100
90
  }
101
- if (hasListener("onStartTranscribe")) {
91
+ if (props.onStartTranscribe) {
102
92
  listeners.onStartTranscribe = () => emit("start-transcribe");
103
93
  }
104
- if (hasListener("onCancelTranscribe")) {
94
+ if (props.onCancelTranscribe) {
105
95
  listeners.onCancelTranscribe = () => emit("cancel-transcribe");
106
96
  }
107
- if (hasListener("onFinishTranscribe")) {
97
+ if (props.onFinishTranscribe) {
108
98
  listeners.onFinishTranscribe = () => emit("finish-transcribe");
109
99
  }
110
100
 
@@ -1,7 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import {
3
3
  computed,
4
- getCurrentInstance,
5
4
  nextTick,
6
5
  onBeforeUnmount,
7
6
  onMounted,
@@ -85,10 +84,6 @@ const emit = defineEmits<{
85
84
 
86
85
  const attrs = useAttrs();
87
86
  const config = useCopilotChatConfiguration();
88
- const instance = getCurrentInstance();
89
- const vnodeProps = computed(
90
- () => (instance?.vnode.props ?? {}) as Record<string, unknown>,
91
- );
92
87
 
93
88
  const containerRef = ref<HTMLElement | null>(null);
94
89
  const isRendered = ref(config.value?.isModalOpen ?? false);
@@ -99,7 +94,6 @@ let focusTimer: ReturnType<typeof setTimeout> | undefined;
99
94
  const isPopupOpen = computed(() => config.value?.isModalOpen ?? false);
100
95
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
101
96
  const headerTitle = computed(() => labels.value.modalHeaderTitle);
102
- const hasStopAction = computed(() => hasListener("onStop"));
103
97
  const popupAnimationClass = computed(() =>
104
98
  isPopupOpen.value && !isAnimatingOut.value
105
99
  ? "cpk:pointer-events-auto cpk:translate-y-0 cpk:opacity-100 cpk:md:scale-100"
@@ -139,14 +133,6 @@ function dimensionToCss(
139
133
  return `${fallback}px`;
140
134
  }
141
135
 
142
- function hasListener(listenerName: string) {
143
- const listener = vnodeProps.value[listenerName];
144
- if (Array.isArray(listener)) {
145
- return listener.length > 0;
146
- }
147
- return !!listener;
148
- }
149
-
150
136
  function closePopup() {
151
137
  config.value?.setModalOpen?.(false);
152
138
  }
@@ -201,19 +187,19 @@ const chatViewEventProps = computed(() => {
201
187
  onSelectSuggestion: handleSelectSuggestion,
202
188
  };
203
189
 
204
- if (hasStopAction.value) {
190
+ if (props.onStop) {
205
191
  listeners.onStop = handleStop;
206
192
  }
207
- if (hasListener("onAddFile")) {
193
+ if (props.onAddFile) {
208
194
  listeners.onAddFile = handleAddFile;
209
195
  }
210
- if (hasListener("onStartTranscribe")) {
196
+ if (props.onStartTranscribe) {
211
197
  listeners.onStartTranscribe = handleStartTranscribe;
212
198
  }
213
- if (hasListener("onCancelTranscribe")) {
199
+ if (props.onCancelTranscribe) {
214
200
  listeners.onCancelTranscribe = handleCancelTranscribe;
215
201
  }
216
- if (hasListener("onFinishTranscribe")) {
202
+ if (props.onFinishTranscribe) {
217
203
  listeners.onFinishTranscribe = handleFinishTranscribe;
218
204
  }
219
205
 
@@ -18,6 +18,9 @@ const props = withDefaults(defineProps<CopilotPopupWelcomeScreenProps>(), {
18
18
  isRunning: false,
19
19
  inputMode: "input",
20
20
  inputToolsMenu: () => [],
21
+ canStop: undefined,
22
+ canAddFile: undefined,
23
+ canTranscribe: undefined,
21
24
  onAddFile: undefined,
22
25
  onStartTranscribe: undefined,
23
26
  onCancelTranscribe: undefined,
@@ -37,20 +40,47 @@ defineSlots<{
37
40
  const config = useCopilotChatConfiguration();
38
41
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
39
42
 
43
+ function handleStop() {
44
+ props.onStop?.();
45
+ }
46
+
47
+ function handleAddFile() {
48
+ props.onAddFile?.();
49
+ }
50
+
51
+ function handleStartTranscribe() {
52
+ props.onStartTranscribe?.();
53
+ }
54
+
55
+ function handleCancelTranscribe() {
56
+ props.onCancelTranscribe?.();
57
+ }
58
+
59
+ function handleFinishTranscribe() {
60
+ props.onFinishTranscribe?.();
61
+ }
62
+
63
+ async function handleFinishTranscribeWithAudio(audioBlob: Blob) {
64
+ await props.onFinishTranscribeWithAudio?.(audioBlob);
65
+ }
66
+
40
67
  const inputSlotProps = computed<CopilotPopupWelcomeScreenInputSlotProps>(
41
68
  () => ({
42
69
  modelValue: props.modelValue,
43
70
  isRunning: props.isRunning,
44
71
  inputMode: props.inputMode,
45
72
  inputToolsMenu: props.inputToolsMenu,
73
+ canStop: props.canStop ?? Boolean(props.onStop),
74
+ canAddFile: props.canAddFile ?? Boolean(props.onAddFile),
75
+ canTranscribe: props.canTranscribe ?? Boolean(props.onStartTranscribe),
46
76
  onUpdateModelValue: props.onUpdateModelValue,
47
77
  onSubmitMessage: props.onSubmitMessage,
48
- onStop: props.onStop,
49
- onAddFile: props.onAddFile,
50
- onStartTranscribe: props.onStartTranscribe,
51
- onCancelTranscribe: props.onCancelTranscribe,
52
- onFinishTranscribe: props.onFinishTranscribe,
53
- onFinishTranscribeWithAudio: props.onFinishTranscribeWithAudio,
78
+ onStop: handleStop,
79
+ onAddFile: handleAddFile,
80
+ onStartTranscribe: handleStartTranscribe,
81
+ onCancelTranscribe: handleCancelTranscribe,
82
+ onFinishTranscribe: handleFinishTranscribe,
83
+ onFinishTranscribeWithAudio: handleFinishTranscribeWithAudio,
54
84
  }),
55
85
  );
56
86
  const suggestionViewSlotProps =
@@ -22,16 +22,14 @@ function sidebarViewEventBindings(slotProps: CopilotChatViewOverrideSlotProps) {
22
22
  onSubmitMessage: slotProps.onSubmitMessage,
23
23
  onInputChange: slotProps.onInputChange,
24
24
  onSelectSuggestion: slotProps.onSelectSuggestion,
25
- ...(slotProps.onStop ? { onStop: slotProps.onStop } : {}),
26
- ...(slotProps.onAddFile ? { onAddFile: slotProps.onAddFile } : {}),
27
- ...(slotProps.onStartTranscribe
28
- ? { onStartTranscribe: slotProps.onStartTranscribe }
29
- : {}),
30
- ...(slotProps.onCancelTranscribe
31
- ? { onCancelTranscribe: slotProps.onCancelTranscribe }
32
- : {}),
33
- ...(slotProps.onFinishTranscribe
34
- ? { onFinishTranscribe: slotProps.onFinishTranscribe }
25
+ ...(slotProps.canStop ? { onStop: slotProps.onStop } : {}),
26
+ ...(slotProps.canAddFile ? { onAddFile: slotProps.onAddFile } : {}),
27
+ ...(slotProps.canTranscribe
28
+ ? {
29
+ onStartTranscribe: slotProps.onStartTranscribe,
30
+ onCancelTranscribe: slotProps.onCancelTranscribe,
31
+ onFinishTranscribe: slotProps.onFinishTranscribe,
32
+ }
35
33
  : {}),
36
34
  };
37
35
  }
@@ -1,5 +1,5 @@
1
1
  <script setup lang="ts">
2
- import { computed, getCurrentInstance, useAttrs } from "vue";
2
+ import { computed, useAttrs } from "vue";
3
3
  import CopilotChatConfigurationProvider from "../../providers/CopilotChatConfigurationProvider.vue";
4
4
  import CopilotSidebarViewInternal from "./CopilotSidebarViewInternal.vue";
5
5
  import type {
@@ -71,10 +71,6 @@ const emit = defineEmits<{
71
71
  }>();
72
72
 
73
73
  const attrs = useAttrs();
74
- const instance = getCurrentInstance();
75
- const vnodeProps = computed(
76
- () => (instance?.vnode.props ?? {}) as Record<string, unknown>,
77
- );
78
74
 
79
75
  const internalProps = computed(() => {
80
76
  const { defaultOpen: _defaultOpen, ...rest } = props;
@@ -86,18 +82,9 @@ const internalBindings = computed(() => ({
86
82
  ...forwardedEventListeners.value,
87
83
  }));
88
84
 
89
- function hasListener(listenerName: string) {
90
- const listener = vnodeProps.value[listenerName];
91
- if (Array.isArray(listener)) {
92
- return listener.length > 0;
93
- }
94
- return !!listener;
95
- }
96
-
97
85
  const forwardedEventListeners = computed(() => {
98
86
  const listeners: Record<string, unknown> = {
99
87
  onSubmitMessage: (value: string) => emit("submit-message", value),
100
- onStop: () => emit("stop"),
101
88
  onInputChange: (value: string) => emit("input-change", value),
102
89
  onSelectSuggestion: (
103
90
  suggestion: (typeof props.suggestions)[number],
@@ -105,16 +92,19 @@ const forwardedEventListeners = computed(() => {
105
92
  ) => emit("select-suggestion", suggestion, index),
106
93
  };
107
94
 
108
- if (hasListener("onAddFile")) {
95
+ if (props.onStop) {
96
+ listeners.onStop = () => emit("stop");
97
+ }
98
+ if (props.onAddFile) {
109
99
  listeners.onAddFile = () => emit("add-file");
110
100
  }
111
- if (hasListener("onStartTranscribe")) {
101
+ if (props.onStartTranscribe) {
112
102
  listeners.onStartTranscribe = () => emit("start-transcribe");
113
103
  }
114
- if (hasListener("onCancelTranscribe")) {
104
+ if (props.onCancelTranscribe) {
115
105
  listeners.onCancelTranscribe = () => emit("cancel-transcribe");
116
106
  }
117
- if (hasListener("onFinishTranscribe")) {
107
+ if (props.onFinishTranscribe) {
118
108
  listeners.onFinishTranscribe = () => emit("finish-transcribe");
119
109
  }
120
110
 
@@ -1,7 +1,6 @@
1
1
  <script setup lang="ts">
2
2
  import {
3
3
  computed,
4
- getCurrentInstance,
5
4
  nextTick,
6
5
  onBeforeUnmount,
7
6
  onMounted,
@@ -82,10 +81,6 @@ const emit = defineEmits<{
82
81
 
83
82
  const attrs = useAttrs();
84
83
  const config = useCopilotChatConfiguration();
85
- const instance = getCurrentInstance();
86
- const vnodeProps = computed(
87
- () => (instance?.vnode.props ?? {}) as Record<string, unknown>,
88
- );
89
84
 
90
85
  const sidebarRef = ref<HTMLElement | null>(null);
91
86
  const measuredSidebarWidth = ref<number | string>(
@@ -115,7 +110,6 @@ const asideAttrs = computed(() => {
115
110
  const { class: _className, ...rest } = attrs;
116
111
  return rest;
117
112
  });
118
- const hasStopAction = computed(() => hasListener("onStop"));
119
113
  const asideStyle = computed(
120
114
  () =>
121
115
  ({
@@ -135,14 +129,6 @@ const bodyMarginStyle = computed(
135
129
  `,
136
130
  );
137
131
 
138
- function hasListener(listenerName: string) {
139
- const listener = vnodeProps.value[listenerName];
140
- if (Array.isArray(listener)) {
141
- return listener.length > 0;
142
- }
143
- return !!listener;
144
- }
145
-
146
132
  function widthToCss(width: number | string): string {
147
133
  return typeof width === "number" ? `${width}px` : width;
148
134
  }
@@ -216,19 +202,19 @@ const chatViewEventProps = computed(() => {
216
202
  onSelectSuggestion: handleSelectSuggestion,
217
203
  };
218
204
 
219
- if (hasStopAction.value) {
205
+ if (props.onStop) {
220
206
  listeners.onStop = handleStop;
221
207
  }
222
- if (hasListener("onAddFile")) {
208
+ if (props.onAddFile) {
223
209
  listeners.onAddFile = handleAddFile;
224
210
  }
225
- if (hasListener("onStartTranscribe")) {
211
+ if (props.onStartTranscribe) {
226
212
  listeners.onStartTranscribe = handleStartTranscribe;
227
213
  }
228
- if (hasListener("onCancelTranscribe")) {
214
+ if (props.onCancelTranscribe) {
229
215
  listeners.onCancelTranscribe = handleCancelTranscribe;
230
216
  }
231
- if (hasListener("onFinishTranscribe")) {
217
+ if (props.onFinishTranscribe) {
232
218
  listeners.onFinishTranscribe = handleFinishTranscribe;
233
219
  }
234
220
 
@@ -18,6 +18,9 @@ const props = withDefaults(defineProps<CopilotSidebarWelcomeScreenProps>(), {
18
18
  isRunning: false,
19
19
  inputMode: "input",
20
20
  inputToolsMenu: () => [],
21
+ canStop: undefined,
22
+ canAddFile: undefined,
23
+ canTranscribe: undefined,
21
24
  onAddFile: undefined,
22
25
  onStartTranscribe: undefined,
23
26
  onCancelTranscribe: undefined,
@@ -37,20 +40,47 @@ defineSlots<{
37
40
  const config = useCopilotChatConfiguration();
38
41
  const labels = computed(() => config.value?.labels ?? CopilotChatDefaultLabels);
39
42
 
43
+ function handleStop() {
44
+ props.onStop?.();
45
+ }
46
+
47
+ function handleAddFile() {
48
+ props.onAddFile?.();
49
+ }
50
+
51
+ function handleStartTranscribe() {
52
+ props.onStartTranscribe?.();
53
+ }
54
+
55
+ function handleCancelTranscribe() {
56
+ props.onCancelTranscribe?.();
57
+ }
58
+
59
+ function handleFinishTranscribe() {
60
+ props.onFinishTranscribe?.();
61
+ }
62
+
63
+ async function handleFinishTranscribeWithAudio(audioBlob: Blob) {
64
+ await props.onFinishTranscribeWithAudio?.(audioBlob);
65
+ }
66
+
40
67
  const inputSlotProps = computed<CopilotSidebarWelcomeScreenInputSlotProps>(
41
68
  () => ({
42
69
  modelValue: props.modelValue,
43
70
  isRunning: props.isRunning,
44
71
  inputMode: props.inputMode,
45
72
  inputToolsMenu: props.inputToolsMenu,
73
+ canStop: props.canStop ?? Boolean(props.onStop),
74
+ canAddFile: props.canAddFile ?? Boolean(props.onAddFile),
75
+ canTranscribe: props.canTranscribe ?? Boolean(props.onStartTranscribe),
46
76
  onUpdateModelValue: props.onUpdateModelValue,
47
77
  onSubmitMessage: props.onSubmitMessage,
48
- onStop: props.onStop,
49
- onAddFile: props.onAddFile,
50
- onStartTranscribe: props.onStartTranscribe,
51
- onCancelTranscribe: props.onCancelTranscribe,
52
- onFinishTranscribe: props.onFinishTranscribe,
53
- onFinishTranscribeWithAudio: props.onFinishTranscribeWithAudio,
78
+ onStop: handleStop,
79
+ onAddFile: handleAddFile,
80
+ onStartTranscribe: handleStartTranscribe,
81
+ onCancelTranscribe: handleCancelTranscribe,
82
+ onFinishTranscribe: handleFinishTranscribe,
83
+ onFinishTranscribeWithAudio: handleFinishTranscribeWithAudio,
54
84
  }),
55
85
  );
56
86
  const suggestionViewSlotProps =