@meistrari/chat-nuxt 4.4.0-rc.8 → 4.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/module.json +1 -1
- package/dist/module.mjs +5 -0
- package/dist/runtime/conversations/components/chat-conversation-item.vue +50 -69
- package/dist/runtime/conversations/components/chat-conversation-list.vue +84 -61
- package/dist/runtime/conversations/composables/conversation-item.js +4 -0
- package/dist/runtime/conversations/composables/conversation-list.d.ts +2 -0
- package/dist/runtime/conversations/composables/conversation-list.js +33 -4
- package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +6 -2
- package/dist/runtime/embed/components/chat-embed-inner.vue +13 -2
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +6 -2
- package/dist/runtime/embed/components/chat-embed.d.vue.ts +4 -2
- package/dist/runtime/embed/components/chat-embed.vue +3 -0
- package/dist/runtime/embed/components/chat-embed.vue.d.ts +4 -2
- package/dist/runtime/embed/components/chat-topbar.d.vue.ts +11 -1
- package/dist/runtime/embed/components/chat-topbar.vue +7 -8
- package/dist/runtime/embed/components/chat-topbar.vue.d.ts +11 -1
- package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +2 -0
- package/dist/runtime/embed/components/meistrari-chat-embed.vue +3 -0
- package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +2 -0
- package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue +0 -1
- package/dist/runtime/messages/components/chat-message-input.vue +148 -138
- package/dist/runtime/messages/components/chat-message-list.vue +6 -10
- package/dist/runtime/messages/components/chat-reasoning-effort-selector.vue +11 -7
- package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +1 -1
- package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.d.vue.ts +4 -1
- package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.vue +15 -3
- package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.vue.d.ts +4 -1
- package/package.json +2 -2
|
@@ -14,7 +14,11 @@ type __VLS_Props = {
|
|
|
14
14
|
showUsageTab?: boolean;
|
|
15
15
|
showDebugOption?: boolean;
|
|
16
16
|
};
|
|
17
|
-
declare
|
|
17
|
+
declare var __VLS_1: {};
|
|
18
|
+
type __VLS_Slots = {} & {
|
|
19
|
+
leading?: (props: typeof __VLS_1) => any;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
22
|
delete: () => any;
|
|
19
23
|
rename: () => any;
|
|
20
24
|
duplicate: () => any;
|
|
@@ -39,5 +43,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
39
43
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
40
44
|
"onUpdate:isEditing"?: ((value: boolean) => any) | undefined;
|
|
41
45
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
46
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
42
47
|
declare const _default: typeof __VLS_export;
|
|
43
48
|
export default _default;
|
|
49
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
50
|
+
new (): {
|
|
51
|
+
$slots: S;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -21,7 +21,7 @@ const titleInputRef = ref(null);
|
|
|
21
21
|
const currentTab = computed(() => props.activeTab ?? "chat");
|
|
22
22
|
const tabOptions = computed(() => {
|
|
23
23
|
const options = [
|
|
24
|
-
{ id: "chat", name: "
|
|
24
|
+
{ id: "chat", name: "Conversa" },
|
|
25
25
|
{ id: "files", name: "Arquivos", count: props.filesCount }
|
|
26
26
|
];
|
|
27
27
|
if (props.showUsageTab) {
|
|
@@ -62,7 +62,7 @@ const headerMenuItems = computed(() => {
|
|
|
62
62
|
}
|
|
63
63
|
items.push({
|
|
64
64
|
label: "Excluir",
|
|
65
|
-
icon: "i-ph-trash",
|
|
65
|
+
icon: "i-ph-trash-bold",
|
|
66
66
|
color: "negative",
|
|
67
67
|
click: () => emit("delete")
|
|
68
68
|
});
|
|
@@ -90,13 +90,12 @@ watch(() => props.isEditing, (editing) => {
|
|
|
90
90
|
<template>
|
|
91
91
|
<div
|
|
92
92
|
flex items-center gap-16px
|
|
93
|
-
pl-
|
|
94
|
-
|
|
95
|
-
bg="white/94"
|
|
96
|
-
backdrop-blur-sm
|
|
97
|
-
absolute top-0 right-0 z-10
|
|
93
|
+
pl-16px pr-16px h-56px
|
|
94
|
+
absolute top-0 right-0 z-10 class="bg-gradient-to-b from-white to-transparent"
|
|
98
95
|
:style="{ left: 'var(--chat-panel-offset)' }"
|
|
99
96
|
>
|
|
97
|
+
<slot name="leading" />
|
|
98
|
+
|
|
100
99
|
<div flex="~ col 1" gap-1.5px min-w-0>
|
|
101
100
|
<div
|
|
102
101
|
v-if="isEditing"
|
|
@@ -160,7 +159,7 @@ watch(() => props.isEditing, (editing) => {
|
|
|
160
159
|
</div>
|
|
161
160
|
</div>
|
|
162
161
|
|
|
163
|
-
<div flex="~" items-center shrink-0>
|
|
162
|
+
<div flex="~" items-center shrink-0 absolute top="50%" left="50%" translate-x="-50%" translate-y="-50%">
|
|
164
163
|
<div p-4px bg-muted rounded-12px flex="~" items-center>
|
|
165
164
|
<button
|
|
166
165
|
v-for="option in tabOptions"
|
|
@@ -14,7 +14,11 @@ type __VLS_Props = {
|
|
|
14
14
|
showUsageTab?: boolean;
|
|
15
15
|
showDebugOption?: boolean;
|
|
16
16
|
};
|
|
17
|
-
declare
|
|
17
|
+
declare var __VLS_1: {};
|
|
18
|
+
type __VLS_Slots = {} & {
|
|
19
|
+
leading?: (props: typeof __VLS_1) => any;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
22
|
delete: () => any;
|
|
19
23
|
rename: () => any;
|
|
20
24
|
duplicate: () => any;
|
|
@@ -39,5 +43,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
39
43
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
40
44
|
"onUpdate:isEditing"?: ((value: boolean) => any) | undefined;
|
|
41
45
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
46
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
42
47
|
declare const _default: typeof __VLS_export;
|
|
43
48
|
export default _default;
|
|
49
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
50
|
+
new (): {
|
|
51
|
+
$slots: S;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
@@ -24,6 +24,8 @@ type MeistrariChatEmbedEmits = {
|
|
|
24
24
|
type MeistrariChatEmbedSlots = SlotsType<{
|
|
25
25
|
/** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. Page variant only. */
|
|
26
26
|
'sidebar-bottom'?: () => any;
|
|
27
|
+
/** Rendered at the start of the conversation topbar, before the title. Page variant only. */
|
|
28
|
+
'topbar-leading'?: () => any;
|
|
27
29
|
/** Rendered inside a failed assistant message's error box, next to "Tentar novamente"; receives the failed message. */
|
|
28
30
|
'failed-message-actions'?: (props: { message: Message }) => any;
|
|
29
31
|
}>;
|
|
@@ -118,6 +118,9 @@ const widgetEmbedProps = computed(() => ({
|
|
|
118
118
|
<template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
|
|
119
119
|
<slot name="sidebar-bottom" />
|
|
120
120
|
</template>
|
|
121
|
+
<template v-if="$slots['topbar-leading']" #topbar-leading>
|
|
122
|
+
<slot name="topbar-leading" />
|
|
123
|
+
</template>
|
|
121
124
|
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
122
125
|
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
123
126
|
</template>
|
|
@@ -24,6 +24,8 @@ type MeistrariChatEmbedEmits = {
|
|
|
24
24
|
type MeistrariChatEmbedSlots = SlotsType<{
|
|
25
25
|
/** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. Page variant only. */
|
|
26
26
|
'sidebar-bottom'?: () => any;
|
|
27
|
+
/** Rendered at the start of the conversation topbar, before the title. Page variant only. */
|
|
28
|
+
'topbar-leading'?: () => any;
|
|
27
29
|
/** Rendered inside a failed assistant message's error box, next to "Tentar novamente"; receives the failed message. */
|
|
28
30
|
'failed-message-actions'?: (props: { message: Message }) => any;
|
|
29
31
|
}>;
|
|
@@ -283,7 +283,6 @@ async function handleConversationDrop(event, groupId) {
|
|
|
283
283
|
<ChatConversationNewGroupButton />
|
|
284
284
|
</div>
|
|
285
285
|
<ChatConversationSearch v-model="conversationSearch" />
|
|
286
|
-
<ChatConversationCreatorFilter />
|
|
287
286
|
</div>
|
|
288
287
|
|
|
289
288
|
<div flex-1 overflow-y-auto px-8px pb-8px>
|
|
@@ -137,6 +137,11 @@ const submitStatus = computed(() => {
|
|
|
137
137
|
const promptShellLocked = computed(
|
|
138
138
|
() => isLocked.value && submitStatus.value !== "streaming"
|
|
139
139
|
);
|
|
140
|
+
const showStopRun = computed(() => submitStatus.value === "streaming");
|
|
141
|
+
watch(editorRef, (editor) => {
|
|
142
|
+
if (editor && content.value && !editor.textContent)
|
|
143
|
+
setDraft(content.value);
|
|
144
|
+
});
|
|
140
145
|
watch(agentInputVariables, (variables) => {
|
|
141
146
|
const variableNames = new Set(variables.map((input) => input.name));
|
|
142
147
|
agentInputTexts.value = Object.fromEntries(
|
|
@@ -636,152 +641,157 @@ defineExpose({
|
|
|
636
641
|
its nearest positioned ancestor; a positioned wrapper here
|
|
637
642
|
would shrink the input. The dropdown positions itself fixed
|
|
638
643
|
from the caret rect, so it needs no relative ancestor. -->
|
|
639
|
-
<
|
|
640
|
-
<
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
644
|
+
<AnimatePresence mode="popLayout" :initial="false">
|
|
645
|
+
<TelaChatAnimateEnter v-if="showStopRun" key="stop-run">
|
|
646
|
+
<TelaChatStopRunButton label="Parar geração" @stop="emit('cancel')" />
|
|
647
|
+
</TelaChatAnimateEnter>
|
|
648
|
+
<TelaChatAnimateEnter v-else key="prompt-input">
|
|
649
|
+
<ChatMentionDropdown
|
|
650
|
+
v-if="mentionAutocomplete.isOpen"
|
|
651
|
+
:items="mentionAutocomplete.filteredItems"
|
|
652
|
+
:commands="mentionAutocomplete.filteredCommands"
|
|
653
|
+
:highlighted-index="mentionAutocomplete.highlightedIndex"
|
|
654
|
+
:trigger="mentionAutocomplete.activeTrigger"
|
|
655
|
+
:query="mentionAutocomplete.query"
|
|
656
|
+
:caret-rect="mentionAutocomplete.triggerCaretRect"
|
|
657
|
+
@select="mentionAutocomplete.selectItem"
|
|
658
|
+
@select-command="mentionAutocomplete.runCommand"
|
|
659
|
+
/>
|
|
651
660
|
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
>
|
|
663
|
-
<select
|
|
664
|
-
v-if="fileInputVariables.length > 0"
|
|
665
|
-
class="agent-file-variable-select"
|
|
666
|
-
:value="pendingFile.inputName ?? ''"
|
|
667
|
-
:disabled="isLocked"
|
|
668
|
-
@change="updatePendingFileInput(pendingFile.id, $event)"
|
|
669
|
-
@click.stop
|
|
661
|
+
<TelaChatPromptInput :locked="promptShellLocked" :class="centered && 'bg-white'">
|
|
662
|
+
<TelaChatPromptInputAttachments v-if="hasAttachments">
|
|
663
|
+
<TelaChatPromptInputAttachment
|
|
664
|
+
v-for="pendingFile in pendingFiles"
|
|
665
|
+
:key="pendingFile.id"
|
|
666
|
+
:name="pendingFile.file.name"
|
|
667
|
+
:icon="getFileIcon(getPendingFileMimeType(pendingFile))"
|
|
668
|
+
:meta="formatFileSize(pendingFile.file.size)"
|
|
669
|
+
remove-label="Remover anexo"
|
|
670
|
+
@remove="removeFile(pendingFile.id)"
|
|
670
671
|
>
|
|
671
|
-
<
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
672
|
+
<select
|
|
673
|
+
v-if="fileInputVariables.length > 0"
|
|
674
|
+
class="agent-file-variable-select"
|
|
675
|
+
:value="pendingFile.inputName ?? ''"
|
|
676
|
+
:disabled="isLocked"
|
|
677
|
+
@change="updatePendingFileInput(pendingFile.id, $event)"
|
|
678
|
+
@click.stop
|
|
678
679
|
>
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
:disabled="isLocked"
|
|
687
|
-
/>
|
|
688
|
-
</TelaChatPromptInputAttachments>
|
|
689
|
-
|
|
690
|
-
<TelaChatPromptInputTextarea
|
|
691
|
-
ref="promptTextareaRef"
|
|
692
|
-
data-testid="chat-message-input"
|
|
693
|
-
placeholder="Escreva sua mensagem..."
|
|
694
|
-
:empty="!content.trim()"
|
|
695
|
-
:flush="hasAttachments"
|
|
696
|
-
:disabled="isLocked"
|
|
697
|
-
@keydown="handleKeydown"
|
|
698
|
-
@input="handleInput"
|
|
699
|
-
@paste="handlePaste"
|
|
700
|
-
@blur="handleBlur"
|
|
701
|
-
/>
|
|
702
|
-
|
|
703
|
-
<TelaChatPromptInputToolbar>
|
|
704
|
-
<TelaChatPromptInputTools>
|
|
705
|
-
<TelaChatPromptInputActionMenu>
|
|
706
|
-
<TelaChatPromptInputActionMenuTrigger :locked="isLocked" label="Abrir menu de ações" />
|
|
707
|
-
<TelaChatPromptInputActionMenuContent>
|
|
708
|
-
<TelaChatPromptInputActionMenuItem
|
|
709
|
-
icon="i-ph-paperclip"
|
|
710
|
-
:disabled="isLocked"
|
|
711
|
-
@click="openFileDialog()"
|
|
680
|
+
<option value="" disabled>
|
|
681
|
+
Selecionar variável
|
|
682
|
+
</option>
|
|
683
|
+
<option
|
|
684
|
+
v-for="input in fileInputVariables"
|
|
685
|
+
:key="input.id || input.name"
|
|
686
|
+
:value="input.name"
|
|
712
687
|
>
|
|
713
|
-
|
|
714
|
-
</
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
Arquivos recentes
|
|
718
|
-
</TelaChatPromptInputActionMenuSubTrigger>
|
|
719
|
-
<TelaChatPromptInputActionMenuSubContent>
|
|
720
|
-
<TelaChatPromptInputActionMenuItem v-if="!fileItems.length" class="text-center" disabled>
|
|
721
|
-
Nenhum arquivo recente
|
|
722
|
-
</TelaChatPromptInputActionMenuItem>
|
|
723
|
-
<TelaChatPromptInputActionMenuItem
|
|
724
|
-
v-for="file in fileItems"
|
|
725
|
-
:key="file.id"
|
|
726
|
-
@click="insertMentionFromMenu(file)"
|
|
727
|
-
>
|
|
728
|
-
<img :src="file.iconUrl" class="w-16px h-16px mr-8px shrink-0" alt="">
|
|
729
|
-
<span class="min-w-0 max-w-200px truncate">{{ file.label }}</span>
|
|
730
|
-
</TelaChatPromptInputActionMenuItem>
|
|
731
|
-
</TelaChatPromptInputActionMenuSubContent>
|
|
732
|
-
</TelaChatPromptInputActionMenuSub>
|
|
733
|
-
<TelaMenubarSeparator />
|
|
734
|
-
<TelaChatPromptInputActionMenuSub>
|
|
735
|
-
<TelaChatPromptInputActionMenuSubTrigger icon="i-ph-notepad" icon-size="16px">
|
|
736
|
-
Skills
|
|
737
|
-
</TelaChatPromptInputActionMenuSubTrigger>
|
|
738
|
-
<TelaChatPromptInputActionMenuSubContent>
|
|
739
|
-
<TelaChatPromptInputActionMenuItem v-if="!skillItems.length" class="text-center" disabled>
|
|
740
|
-
Nenhuma skill disponível
|
|
741
|
-
</TelaChatPromptInputActionMenuItem>
|
|
742
|
-
<TelaChatPromptInputActionMenuItem
|
|
743
|
-
v-for="skill in skillItems"
|
|
744
|
-
:key="skill.id"
|
|
745
|
-
@click="insertMentionFromMenu(skill)"
|
|
746
|
-
>
|
|
747
|
-
<span class="min-w-0 max-w-200px truncate">{{ skill.label }}</span>
|
|
748
|
-
</TelaChatPromptInputActionMenuItem>
|
|
749
|
-
</TelaChatPromptInputActionMenuSubContent>
|
|
750
|
-
</TelaChatPromptInputActionMenuSub>
|
|
751
|
-
</TelaChatPromptInputActionMenuContent>
|
|
752
|
-
</TelaChatPromptInputActionMenu>
|
|
688
|
+
{{ input.name }}
|
|
689
|
+
</option>
|
|
690
|
+
</select>
|
|
691
|
+
</TelaChatPromptInputAttachment>
|
|
753
692
|
<component
|
|
754
|
-
:is="composerExtension.
|
|
755
|
-
v-if="composerExtension?.
|
|
693
|
+
:is="composerExtension.attachmentsComponent"
|
|
694
|
+
v-if="composerExtension?.attachmentsComponent"
|
|
756
695
|
:disabled="isLocked"
|
|
757
696
|
/>
|
|
758
|
-
</
|
|
697
|
+
</TelaChatPromptInputAttachments>
|
|
759
698
|
|
|
760
|
-
<
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
699
|
+
<TelaChatPromptInputTextarea
|
|
700
|
+
ref="promptTextareaRef"
|
|
701
|
+
data-testid="chat-message-input"
|
|
702
|
+
placeholder="Escreva sua mensagem..."
|
|
703
|
+
:empty="!content.trim()"
|
|
704
|
+
:flush="hasAttachments"
|
|
705
|
+
:disabled="isLocked"
|
|
706
|
+
@keydown="handleKeydown"
|
|
707
|
+
@input="handleInput"
|
|
708
|
+
@paste="handlePaste"
|
|
709
|
+
@blur="handleBlur"
|
|
710
|
+
/>
|
|
711
|
+
|
|
712
|
+
<TelaChatPromptInputToolbar>
|
|
713
|
+
<TelaChatPromptInputTools>
|
|
714
|
+
<TelaChatPromptInputActionMenu>
|
|
715
|
+
<TelaChatPromptInputActionMenuTrigger :locked="isLocked" label="Abrir menu de ações" />
|
|
716
|
+
<TelaChatPromptInputActionMenuContent>
|
|
717
|
+
<TelaChatPromptInputActionMenuItem
|
|
718
|
+
icon="i-ph-paperclip"
|
|
719
|
+
:disabled="isLocked"
|
|
720
|
+
@click="openFileDialog()"
|
|
721
|
+
>
|
|
722
|
+
Adicionar arquivos ou fotos
|
|
723
|
+
</TelaChatPromptInputActionMenuItem>
|
|
724
|
+
<TelaChatPromptInputActionMenuSub>
|
|
725
|
+
<TelaChatPromptInputActionMenuSubTrigger icon="i-ph-clock-counter-clockwise">
|
|
726
|
+
Arquivos recentes
|
|
727
|
+
</TelaChatPromptInputActionMenuSubTrigger>
|
|
728
|
+
<TelaChatPromptInputActionMenuSubContent>
|
|
729
|
+
<TelaChatPromptInputActionMenuItem v-if="!fileItems.length" class="text-center" disabled>
|
|
730
|
+
Nenhum arquivo recente
|
|
731
|
+
</TelaChatPromptInputActionMenuItem>
|
|
732
|
+
<TelaChatPromptInputActionMenuItem
|
|
733
|
+
v-for="file in fileItems"
|
|
734
|
+
:key="file.id"
|
|
735
|
+
@click="insertMentionFromMenu(file)"
|
|
736
|
+
>
|
|
737
|
+
<img :src="file.iconUrl" class="w-16px h-16px mr-8px shrink-0" alt="">
|
|
738
|
+
<span class="min-w-0 max-w-200px truncate">{{ file.label }}</span>
|
|
739
|
+
</TelaChatPromptInputActionMenuItem>
|
|
740
|
+
</TelaChatPromptInputActionMenuSubContent>
|
|
741
|
+
</TelaChatPromptInputActionMenuSub>
|
|
742
|
+
<TelaMenubarSeparator />
|
|
743
|
+
<TelaChatPromptInputActionMenuSub>
|
|
744
|
+
<TelaChatPromptInputActionMenuSubTrigger icon="i-ph-notepad" icon-size="16px">
|
|
745
|
+
Skills
|
|
746
|
+
</TelaChatPromptInputActionMenuSubTrigger>
|
|
747
|
+
<TelaChatPromptInputActionMenuSubContent>
|
|
748
|
+
<TelaChatPromptInputActionMenuItem v-if="!skillItems.length" class="text-center" disabled>
|
|
749
|
+
Nenhuma skill disponível
|
|
750
|
+
</TelaChatPromptInputActionMenuItem>
|
|
751
|
+
<TelaChatPromptInputActionMenuItem
|
|
752
|
+
v-for="skill in skillItems"
|
|
753
|
+
:key="skill.id"
|
|
754
|
+
@click="insertMentionFromMenu(skill)"
|
|
755
|
+
>
|
|
756
|
+
<span class="min-w-0 max-w-200px truncate">{{ skill.label }}</span>
|
|
757
|
+
</TelaChatPromptInputActionMenuItem>
|
|
758
|
+
</TelaChatPromptInputActionMenuSubContent>
|
|
759
|
+
</TelaChatPromptInputActionMenuSub>
|
|
760
|
+
</TelaChatPromptInputActionMenuContent>
|
|
761
|
+
</TelaChatPromptInputActionMenu>
|
|
762
|
+
<component
|
|
763
|
+
:is="composerExtension.component"
|
|
764
|
+
v-if="composerExtension?.component"
|
|
765
|
+
:disabled="isLocked"
|
|
766
|
+
/>
|
|
767
|
+
</TelaChatPromptInputTools>
|
|
768
|
+
|
|
769
|
+
<TelaChatPromptInputActions>
|
|
770
|
+
<ChatReasoningEffortSelector
|
|
771
|
+
v-model="selectedReasoningEffort"
|
|
772
|
+
:disabled="isLocked"
|
|
773
|
+
@click.stop
|
|
774
|
+
/>
|
|
775
|
+
<ChatModelSelector
|
|
776
|
+
v-model="selectedModel"
|
|
777
|
+
:disabled="isLocked"
|
|
778
|
+
@click.stop
|
|
779
|
+
/>
|
|
780
|
+
<TelaChatPromptSubmitButton
|
|
781
|
+
data-testid="chat-message-submit"
|
|
782
|
+
:status="submitStatus"
|
|
783
|
+
:disabled="!canSend"
|
|
784
|
+
send-label="Enviar mensagem"
|
|
785
|
+
stop-label="Parar geração"
|
|
786
|
+
uploading-label="Enviando anexos"
|
|
787
|
+
@send="handleSend"
|
|
788
|
+
@stop="emit('cancel')"
|
|
789
|
+
/>
|
|
790
|
+
</TelaChatPromptInputActions>
|
|
791
|
+
</TelaChatPromptInputToolbar>
|
|
792
|
+
</TelaChatPromptInput>
|
|
793
|
+
</TelaChatAnimateEnter>
|
|
794
|
+
</AnimatePresence>
|
|
785
795
|
</div>
|
|
786
796
|
</div>
|
|
787
797
|
</template>
|
|
@@ -95,11 +95,8 @@ defineExpose({
|
|
|
95
95
|
>
|
|
96
96
|
<TelaChatConversation
|
|
97
97
|
ref="conversationRef"
|
|
98
|
-
:scroll-area="variant
|
|
99
|
-
:class="{
|
|
100
|
-
'pt-72px!': (variant ?? 'page') === 'page',
|
|
101
|
-
'pt-72px pb-24px px-16px': variant === 'mobile'
|
|
102
|
-
}"
|
|
98
|
+
:scroll-area="variant !== 'mobile'"
|
|
99
|
+
:class="{ 'pb-24px px-16px': variant === 'mobile' }"
|
|
103
100
|
>
|
|
104
101
|
<TelaChatConversationContent class="max-w-700px! min-h-full">
|
|
105
102
|
<template v-if="loading">
|
|
@@ -152,19 +149,18 @@ defineExpose({
|
|
|
152
149
|
<button
|
|
153
150
|
v-if="!isPinned && hasRoomBelow"
|
|
154
151
|
type="button"
|
|
155
|
-
class="chat-message-list__jump"
|
|
156
|
-
bg
|
|
157
|
-
b=".5px border-default"
|
|
152
|
+
absolute z-2 left="50%" class="chat-message-list__jump bottom-[calc(var(--chat-input-height,0px)_+_32px)]"
|
|
153
|
+
bg border-0.5px border inline-flex size-32px flex items-center justify-center rounded-full
|
|
158
154
|
aria-label="Ir para a mensagem mais recente"
|
|
159
155
|
title="Ir para a mensagem mais recente"
|
|
160
156
|
@click="scrollToBottom({ smooth: true })"
|
|
161
157
|
>
|
|
162
|
-
<TelaIcon name="i-ph-arrow-down" size="16px" color="icon-
|
|
158
|
+
<TelaIcon name="i-ph-arrow-down-bold" size="16px" color="icon-tertiary" />
|
|
163
159
|
</button>
|
|
164
160
|
</Transition>
|
|
165
161
|
</div>
|
|
166
162
|
</template>
|
|
167
163
|
|
|
168
164
|
<style scoped>
|
|
169
|
-
.chat-message-list>:deep([data-chat-conversation]){flex:1 1 0%;min-height:0;overflow-y:auto}.chat-message-
|
|
165
|
+
.chat-message-list>:deep([data-chat-conversation]){flex:1 1 0%;min-height:0;overflow-y:auto}.chat-message-list:not([data-variant=widget]) :deep([data-chat-conversation]){padding-top:64px}.chat-message-list[data-variant=page] :deep(.chat-conversation-scrollbar){top:64px!important}.chat-message-list[data-variant=page] :deep(.scroll-fog [data-reka-scroll-area-viewport]){--chat-fog-size:calc(var(--chat-input-height, 64px) + 64px)}.chat-message-list__jump{transform:translateX(-50%);transform-origin:center}.jump-to-latest-enter-active,.jump-to-latest-leave-active{transition:opacity .12s ease,transform .12s ease}.jump-to-latest-enter-from,.jump-to-latest-leave-to{opacity:0;transform:translateX(-50%) scale(.7) translateY(10px)}
|
|
170
166
|
</style>
|
|
@@ -84,24 +84,28 @@ function onKeydown(event) {
|
|
|
84
84
|
<TelaPopoverTrigger as-child>
|
|
85
85
|
<button
|
|
86
86
|
type="button"
|
|
87
|
-
class="
|
|
88
|
-
:class="effort ? 'text-primary' : 'text-secondary'"
|
|
87
|
+
class="group pl-10px pr-8px py-7px rounded-8px flex items-center gap-6px duration-80 text-primary hover:bg-muted data-[state=open]:text-secondary data-[state=open]:bg-muted"
|
|
89
88
|
:disabled="disabled"
|
|
90
89
|
:aria-label="`Esfor\xE7o de racioc\xEDnio: ${selectedOption?.label ?? AGENT_DEFAULT_LABEL}`"
|
|
91
90
|
>
|
|
92
91
|
<span body-14-medium whitespace-nowrap>{{ triggerLabel }}</span>
|
|
93
|
-
<
|
|
92
|
+
<TelaIcon
|
|
93
|
+
name="i-ph-caret-down-bold"
|
|
94
|
+
size="15px"
|
|
95
|
+
color="icon-tertiary"
|
|
96
|
+
class="shrink-0 transition-transform ease-out duration-150 group-data-[state=open]:rotate-180"
|
|
97
|
+
/>
|
|
94
98
|
</button>
|
|
95
99
|
</TelaPopoverTrigger>
|
|
96
100
|
<TelaPopoverContent
|
|
97
101
|
side="top"
|
|
98
102
|
align="end"
|
|
99
|
-
:side-offset="
|
|
100
|
-
class="
|
|
103
|
+
:side-offset="3"
|
|
104
|
+
class="popover-enter-exit origin-[var(--reka-popover-content-transform-origin)] w-260px p-16px rounded-12px! bg border-0.5px! border! [box-shadow:0_4px_16px_0_rgba(85,91,98,0.14)]!"
|
|
101
105
|
>
|
|
102
106
|
<div flex="~ col" gap-16px>
|
|
103
|
-
<div flex="~ col" items-center gap-
|
|
104
|
-
<span body-14-
|
|
107
|
+
<div flex="~ col" items-center gap-2px text-center>
|
|
108
|
+
<span body-14-semibold text-primary>{{ selectedOption?.label ?? AGENT_DEFAULT_LABEL }}</span>
|
|
105
109
|
<span body-12-regular text-secondary>{{ selectedOption?.description ?? AGENT_DEFAULT_DESCRIPTION }}</span>
|
|
106
110
|
</div>
|
|
107
111
|
|
|
@@ -51,7 +51,7 @@ const liveFormattedDuration = computed(() => {
|
|
|
51
51
|
<div class="chat-reasoning-stage" w-full>
|
|
52
52
|
<Transition name="chat-reasoning-presence" :appear="!completed">
|
|
53
53
|
<div v-if="!completed && !hasReasoning" key="thinking" class="chat-reasoning-placeholder">
|
|
54
|
-
<ChatThinkingIndicator />
|
|
54
|
+
<ChatThinkingIndicator :started-at="startedAt" />
|
|
55
55
|
</div>
|
|
56
56
|
|
|
57
57
|
<!-- Com reasoning (loading ou completo): header clicável + steps colapsáveis -->
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
startedAt?: Date | string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
2
5
|
declare const _default: typeof __VLS_export;
|
|
3
6
|
export default _default;
|
|
@@ -5,7 +5,16 @@ import {
|
|
|
5
5
|
getNextChatLoadingMessageIndex,
|
|
6
6
|
resolveChatLoadingMessages
|
|
7
7
|
} from "../../../embed/loading-messages";
|
|
8
|
+
const props = defineProps({
|
|
9
|
+
startedAt: { type: [Date, String], required: false }
|
|
10
|
+
});
|
|
8
11
|
const embedConfig = useEmbedConfig();
|
|
12
|
+
const startedAtMs = computed(() => {
|
|
13
|
+
if (!props.startedAt)
|
|
14
|
+
return void 0;
|
|
15
|
+
const ms = new Date(props.startedAt).getTime();
|
|
16
|
+
return Number.isNaN(ms) ? void 0 : ms;
|
|
17
|
+
});
|
|
9
18
|
const currentTextIndex = ref(0);
|
|
10
19
|
const dotCount = ref(0);
|
|
11
20
|
const loadingState = computed(() => resolveChatLoadingMessages({
|
|
@@ -52,7 +61,10 @@ onUnmounted(() => {
|
|
|
52
61
|
</script>
|
|
53
62
|
|
|
54
63
|
<template>
|
|
55
|
-
<
|
|
56
|
-
|
|
57
|
-
|
|
64
|
+
<div flex flex-col gap-8px>
|
|
65
|
+
<TelaChatWorkingIndicator label="Trabalhando" :started-at="startedAtMs" />
|
|
66
|
+
<TelaChatTextShimmer class="body-16-regular">
|
|
67
|
+
{{ currentText }}
|
|
68
|
+
</TelaChatTextShimmer>
|
|
69
|
+
</div>
|
|
58
70
|
</template>
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
startedAt?: Date | string;
|
|
3
|
+
};
|
|
4
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
2
5
|
declare const _default: typeof __VLS_export;
|
|
3
6
|
export default _default;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/chat-nuxt",
|
|
3
|
-
"version": "4.4.0
|
|
3
|
+
"version": "4.4.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"@iconify/vue": "^5.0.0",
|
|
54
54
|
"@meistrari/auth-nuxt": "3.31.0",
|
|
55
55
|
"@meistrari/logger": "^2.1.3",
|
|
56
|
-
"@meistrari/tela-build": "^1.
|
|
56
|
+
"@meistrari/tela-build": "^1.75.1",
|
|
57
57
|
"@sentry/nuxt": "^10.0.0",
|
|
58
58
|
"@vueuse/components": "^12.8.0",
|
|
59
59
|
"@vueuse/core": "^12.8.0",
|