@meistrari/chat-nuxt 3.9.2 → 3.10.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 (85) hide show
  1. package/README.md +50 -440
  2. package/dist/module.d.mts +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/runtime/assets/css/markstream.css +1 -1
  5. package/dist/runtime/conversations/components/chat-conversation-creator-filter.vue +11 -67
  6. package/dist/runtime/conversations/components/chat-conversation-item.d.vue.ts +2 -1
  7. package/dist/runtime/conversations/components/chat-conversation-item.vue +29 -33
  8. package/dist/runtime/conversations/components/chat-conversation-item.vue.d.ts +2 -1
  9. package/dist/runtime/conversations/components/chat-conversation-list.d.vue.ts +0 -1
  10. package/dist/runtime/conversations/components/chat-conversation-list.vue +117 -158
  11. package/dist/runtime/conversations/components/chat-conversation-list.vue.d.ts +0 -1
  12. package/dist/runtime/conversations/components/chat-conversation-new-group-button.vue +34 -73
  13. package/dist/runtime/conversations/components/chat-conversation-search.vue +1 -21
  14. package/dist/runtime/conversations/components/chat-widget-history-list.d.vue.ts +12 -0
  15. package/dist/runtime/conversations/components/chat-widget-history-list.vue +27 -0
  16. package/dist/runtime/conversations/components/chat-widget-history-list.vue.d.ts +12 -0
  17. package/dist/runtime/conversations/composables/conversation-groups.d.ts +1 -0
  18. package/dist/runtime/conversations/composables/conversation-groups.js +2 -0
  19. package/dist/runtime/conversations/composables/conversation-item.js +4 -4
  20. package/dist/runtime/conversations/composables/conversation-list.js +14 -5
  21. package/dist/runtime/embed/components/chat-configuration-modal.d.vue.ts +3 -3
  22. package/dist/runtime/embed/components/chat-configuration-modal.vue.d.ts +3 -3
  23. package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +6 -3
  24. package/dist/runtime/embed/components/chat-embed-inner.vue +365 -152
  25. package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +6 -3
  26. package/dist/runtime/embed/components/chat-embed.d.vue.ts +31 -4
  27. package/dist/runtime/embed/components/chat-embed.vue +10 -4
  28. package/dist/runtime/embed/components/chat-embed.vue.d.ts +31 -4
  29. package/dist/runtime/embed/components/chat-topbar.vue +83 -85
  30. package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +5 -3
  31. package/dist/runtime/embed/components/meistrari-chat-embed.vue +118 -57
  32. package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +5 -3
  33. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.d.vue.ts +0 -1
  34. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue +2 -45
  35. package/dist/runtime/embed/components/mobile/chat-mobile-drawer.vue.d.ts +0 -1
  36. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.d.vue.ts +9 -5
  37. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.vue +14 -25
  38. package/dist/runtime/embed/components/mobile/chat-mobile-home-suggestions.vue.d.ts +9 -5
  39. package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +4 -4
  40. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue +2 -3
  41. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +4 -4
  42. package/dist/runtime/embed/feature-config.d.ts +7 -0
  43. package/dist/runtime/embed/types.d.ts +47 -8
  44. package/dist/runtime/files/icons.d.ts +1 -1
  45. package/dist/runtime/files/icons.js +1 -1
  46. package/dist/runtime/messages/components/chat-mention-dropdown.d.vue.ts +6 -1
  47. package/dist/runtime/messages/components/chat-mention-dropdown.vue +46 -22
  48. package/dist/runtime/messages/components/chat-mention-dropdown.vue.d.ts +6 -1
  49. package/dist/runtime/messages/components/chat-message-bubble.vue +53 -71
  50. package/dist/runtime/messages/components/chat-message-feedback.vue +25 -229
  51. package/dist/runtime/messages/components/chat-message-input.vue +176 -134
  52. package/dist/runtime/messages/components/chat-message-list.d.vue.ts +6 -0
  53. package/dist/runtime/messages/components/chat-message-list.vue +27 -23
  54. package/dist/runtime/messages/components/chat-message-list.vue.d.ts +6 -0
  55. package/dist/runtime/messages/components/chat-model-selector.vue +10 -22
  56. package/dist/runtime/messages/components/reasoning/chat-reasoning-message.vue +2 -3
  57. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +60 -69
  58. package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.vue +3 -9
  59. package/dist/runtime/messages/components/widgets/chat-bash-widget.vue +3 -12
  60. package/dist/runtime/messages/components/widgets/chat-doc-sdk-widget.vue +3 -12
  61. package/dist/runtime/messages/components/widgets/chat-generic-tool-widget.vue +3 -12
  62. package/dist/runtime/messages/components/widgets/chat-grep-widget.vue +7 -17
  63. package/dist/runtime/messages/components/widgets/chat-read-widget.vue +7 -17
  64. package/dist/runtime/messages/components/widgets/chat-tela-skill-widget.vue +4 -13
  65. package/dist/runtime/messages/components/widgets/chat-thinking-widget.vue +11 -22
  66. package/dist/runtime/messages/components/widgets/chat-web-search-widget.vue +13 -40
  67. package/dist/runtime/messages/components/widgets/chat-workstation-query-widget.vue +52 -65
  68. package/dist/runtime/messages/components/widgets/chat-write-widget.vue +8 -18
  69. package/dist/runtime/messages/composables/mention-autocomplete.js +4 -0
  70. package/dist/runtime/messages/message-state.js +1 -0
  71. package/dist/runtime/public/files/generic.svg +2 -5
  72. package/dist/runtime/public/files/image.svg +2 -1
  73. package/dist/runtime/types/embed.d.ts +1 -1
  74. package/dist/runtime/types/schemas/chat/conversations.d.ts +2 -0
  75. package/dist/runtime/types/schemas/chat/conversations.js +3 -0
  76. package/dist/runtime/types/schemas/chat/messages.d.ts +4 -0
  77. package/dist/runtime/types/schemas/chat/messages.js +7 -0
  78. package/dist/types.d.mts +1 -1
  79. package/package.json +5 -4
  80. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.d.vue.ts +0 -23
  81. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue +0 -75
  82. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue.d.ts +0 -23
  83. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.d.vue.ts +0 -37
  84. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue +0 -125
  85. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue.d.ts +0 -37
@@ -1,6 +1,6 @@
1
1
  <script setup>
2
- import { computed } from "vue";
3
- const props = defineProps({
2
+ import { computed, ref, watch } from "vue";
3
+ const { hideSidebar = void 0, ...props } = defineProps({
4
4
  conversationId: { type: [String, null], required: false },
5
5
  initialConversationId: { type: [String, null], required: false },
6
6
  conversationScope: { type: [String, null], required: false },
@@ -8,7 +8,8 @@ const props = defineProps({
8
8
  hideSidebar: { type: Boolean, required: false },
9
9
  sidebar: { type: Object, required: false },
10
10
  hideSettings: { type: Boolean, required: false },
11
- hideFolderHint: { type: Boolean, required: false },
11
+ compact: { type: Boolean, required: false },
12
+ suggestions: { type: [Array, null], required: false },
12
13
  loadingMessages: { type: [Array, null], required: false },
13
14
  loadingMessagesMode: { type: [String, null], required: false },
14
15
  customComponents: { type: Object, required: false },
@@ -20,70 +21,130 @@ const props = defineProps({
20
21
  telaAgentInputs: { type: null, required: false },
21
22
  workspaceSettings: { type: null, required: false },
22
23
  user: { type: null, required: false },
23
- features: { type: Object, required: false }
24
+ features: { type: Object, required: false },
25
+ variant: { type: String, required: false },
26
+ defaultOpen: { type: Boolean, required: false },
27
+ launcherLabel: { type: String, required: false }
24
28
  });
25
- defineEmits(["update:conversationId", "action", "messageFeedback", "messageTerminal"]);
29
+ const emit = defineEmits(["update:conversationId", "update:open", "action", "messageFeedback", "messageTerminal"]);
26
30
  defineSlots();
27
31
  const hideSettings = computed(() => props.hideSettings ?? false);
32
+ const variant = computed(() => props.variant ?? "page");
33
+ const isOpen = ref(props.defaultOpen ?? false);
34
+ function setOpen(open) {
35
+ isOpen.value = open;
36
+ emit("update:open", open);
37
+ }
38
+ const widgetConversationId = ref(props.conversationId ?? props.initialConversationId ?? null);
39
+ const widgetConversationTitle = ref(null);
40
+ watch(() => props.conversationId, (value) => {
41
+ if (value !== void 0)
42
+ widgetConversationId.value = value;
43
+ });
44
+ function handleWidgetConversationIdChange(value) {
45
+ widgetConversationId.value = value;
46
+ if (!value)
47
+ widgetConversationTitle.value = null;
48
+ emit("update:conversationId", value);
49
+ }
50
+ function startWidgetConversation() {
51
+ handleWidgetConversationIdChange(null);
52
+ }
53
+ const sharedEmbedProps = computed(() => ({
54
+ conversationId: props.conversationId,
55
+ initialConversationId: props.initialConversationId,
56
+ conversationScope: props.conversationScope,
57
+ defaultConversationCreatorFilter: props.defaultConversationCreatorFilter,
58
+ hideSettings: hideSettings.value,
59
+ suggestions: props.suggestions,
60
+ features: props.features,
61
+ loadingMessages: props.loadingMessages,
62
+ loadingMessagesMode: props.loadingMessagesMode,
63
+ customComponents: props.customComponents,
64
+ customHtmlTags: props.customHtmlTags,
65
+ citations: props.citations,
66
+ feedbackConfig: props.feedbackConfig,
67
+ messageFeedback: props.messageFeedback,
68
+ ...props.telaAgentId ? { telaAgentId: props.telaAgentId, telaAgentInputs: props.telaAgentInputs } : { workspaceSettings: props.workspaceSettings, user: props.user }
69
+ }));
70
+ const pageEmbedProps = computed(() => ({
71
+ ...sharedEmbedProps.value,
72
+ hideSidebar,
73
+ sidebar: props.sidebar
74
+ }));
75
+ const widgetEmbedProps = computed(() => ({
76
+ ...sharedEmbedProps.value,
77
+ conversationId: widgetConversationId.value,
78
+ hideSidebar: hideSidebar ?? true
79
+ }));
28
80
  </script>
29
81
 
30
82
  <template>
31
83
  <ChatEmbed
32
- v-if="telaAgentId"
33
- :tela-agent-id="telaAgentId"
34
- :tela-agent-inputs="telaAgentInputs"
35
- :conversation-id="conversationId"
36
- :initial-conversation-id="initialConversationId"
37
- :conversation-scope="conversationScope"
38
- :default-conversation-creator-filter="defaultConversationCreatorFilter"
39
- :hide-sidebar="hideSidebar"
40
- :sidebar="sidebar"
41
- :hide-settings="hideSettings"
42
- :hide-folder-hint="hideFolderHint"
43
- :features="features"
44
- :loading-messages="loadingMessages"
45
- :loading-messages-mode="loadingMessagesMode"
46
- :custom-components="customComponents"
47
- :custom-html-tags="customHtmlTags"
48
- :citations="citations"
49
- :feedback-config="feedbackConfig"
50
- :message-feedback="messageFeedback"
51
- @update:conversation-id="$emit('update:conversationId', $event)"
52
- @action="$emit('action', $event)"
53
- @message-feedback="$emit('messageFeedback', $event)"
54
- @message-terminal="$emit('messageTerminal', $event)"
55
- >
56
- <template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
57
- <slot name="sidebar-bottom" />
58
- </template>
59
- </ChatEmbed>
60
- <ChatEmbed
61
- v-else
62
- :workspace-settings="workspaceSettings"
63
- :user="user"
64
- :conversation-id="conversationId"
65
- :initial-conversation-id="initialConversationId"
66
- :conversation-scope="conversationScope"
67
- :default-conversation-creator-filter="defaultConversationCreatorFilter"
68
- :hide-sidebar="hideSidebar"
69
- :sidebar="sidebar"
70
- :hide-settings="hideSettings"
71
- :hide-folder-hint="hideFolderHint"
72
- :features="features"
73
- :loading-messages="loadingMessages"
74
- :loading-messages-mode="loadingMessagesMode"
75
- :custom-components="customComponents"
76
- :custom-html-tags="customHtmlTags"
77
- :citations="citations"
78
- :feedback-config="feedbackConfig"
79
- :message-feedback="messageFeedback"
80
- @update:conversation-id="$emit('update:conversationId', $event)"
81
- @action="$emit('action', $event)"
82
- @message-feedback="$emit('messageFeedback', $event)"
83
- @message-terminal="$emit('messageTerminal', $event)"
84
+ v-if="variant === 'page'"
85
+ v-bind="pageEmbedProps"
86
+ @update:conversation-id="emit('update:conversationId', $event)"
87
+ @action="emit('action', $event)"
88
+ @message-feedback="emit('messageFeedback', $event)"
89
+ @message-terminal="emit('messageTerminal', $event)"
84
90
  >
85
91
  <template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
86
92
  <slot name="sidebar-bottom" />
87
93
  </template>
88
94
  </ChatEmbed>
95
+
96
+ <ClientOnly v-else>
97
+ <!-- Floating: popover anchored to the launcher pill -->
98
+ <TelaChatFloatingWindow v-if="variant === 'floating'" :open="isOpen" @update:open="setOpen">
99
+ <template #launcher>
100
+ <TelaChatFloatingWindowTrigger :open="isOpen" :label="props.launcherLabel" />
101
+ </template>
102
+
103
+ <TelaChatWidgetHeader
104
+ :title="widgetConversationTitle ?? void 0"
105
+ @new-conversation="startWidgetConversation"
106
+ @select-conversation="handleWidgetConversationIdChange"
107
+ @close="setOpen(false)"
108
+ >
109
+ <template #history>
110
+ <ChatWidgetHistoryList />
111
+ </template>
112
+ </TelaChatWidgetHeader>
113
+ <div flex-1 min-h-0>
114
+ <ChatEmbed
115
+ v-bind="widgetEmbedProps"
116
+ compact
117
+ @update:conversation-id="handleWidgetConversationIdChange"
118
+ @update:conversation-title="widgetConversationTitle = $event"
119
+ @action="emit('action', $event)"
120
+ @message-feedback="emit('messageFeedback', $event)"
121
+ @message-terminal="emit('messageTerminal', $event)"
122
+ />
123
+ </div>
124
+ </TelaChatFloatingWindow>
125
+
126
+ <!-- Sidepanel: always-open docked panel, no launcher -->
127
+ <TelaChatSidepanelWindow v-else>
128
+ <TelaChatWidgetHeader
129
+ :title="widgetConversationTitle ?? void 0"
130
+ @new-conversation="startWidgetConversation"
131
+ @select-conversation="handleWidgetConversationIdChange"
132
+ >
133
+ <template #history>
134
+ <ChatWidgetHistoryList />
135
+ </template>
136
+ </TelaChatWidgetHeader>
137
+ <div flex-1 min-h-0>
138
+ <ChatEmbed
139
+ v-bind="widgetEmbedProps"
140
+ compact
141
+ @update:conversation-id="handleWidgetConversationIdChange"
142
+ @update:conversation-title="widgetConversationTitle = $event"
143
+ @action="emit('action', $event)"
144
+ @message-feedback="emit('messageFeedback', $event)"
145
+ @message-terminal="emit('messageTerminal', $event)"
146
+ />
147
+ </div>
148
+ </TelaChatSidepanelWindow>
149
+ </ClientOnly>
89
150
  </template>
@@ -3,11 +3,13 @@ import type { ChatActionPayload } from '../../messages/composables/chat-action.j
3
3
  import type { MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
4
4
  import type { ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
5
5
  import type { ChatFeatureConfig } from '../feature-config.js';
6
- import type { ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
6
+ import type { ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
7
7
 
8
8
  type MeistrariChatEmbedEmits = {
9
9
  /** Fired when the active conversation changes. Pairs with `v-model:conversation-id`. */
10
10
  'update:conversationId': (value: string | null) => any;
11
+ /** Fired when the floating widget window opens or closes. Widget variants only. */
12
+ 'update:open': (value: boolean) => any;
11
13
  /** Fired when an assistant message triggers a host-handled action. */
12
14
  'action': (payload: ChatActionPayload) => any;
13
15
  /** Fired when a user submits feedback for an assistant message. */
@@ -17,7 +19,7 @@ type MeistrariChatEmbedEmits = {
17
19
  };
18
20
 
19
21
  type MeistrariChatEmbedSlots = SlotsType<{
20
- /** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. */
22
+ /** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. Page variant only. */
21
23
  'sidebar-bottom'?: () => any;
22
24
  }>;
23
25
 
@@ -50,4 +52,4 @@ type MeistrariChatEmbedSlots = SlotsType<{
50
52
  declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
51
53
 
52
54
  export default MeistrariChatEmbed;
53
- export type { ChatActionPayload, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
55
+ export type { ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
@@ -5,7 +5,6 @@ type __VLS_Props = {
5
5
  conversations: DeepReadonly<Conversation[]>;
6
6
  activeId: string | null;
7
7
  loading?: boolean;
8
- hideFolderHint?: boolean;
9
8
  userName?: string;
10
9
  userEmail?: string;
11
10
  userImage?: string;
@@ -13,7 +13,6 @@ const props = defineProps({
13
13
  conversations: { type: null, required: true },
14
14
  activeId: { type: [String, null], required: true },
15
15
  loading: { type: Boolean, required: false },
16
- hideFolderHint: { type: Boolean, required: false },
17
16
  userName: { type: String, required: false },
18
17
  userEmail: { type: String, required: false },
19
18
  userImage: { type: String, required: false }
@@ -28,7 +27,6 @@ const conversationSearch = ref("");
28
27
  const draggedConversationId = ref(null);
29
28
  const dropTargetGroupId = ref(void 0);
30
29
  const openGroupIds = ref(/* @__PURE__ */ new Set());
31
- const groupsReady = ref(false);
32
30
  let dragOpenGroupTimeout = null;
33
31
  let dragOpenGroupId = null;
34
32
  const embedConfig = useEmbedConfig();
@@ -81,13 +79,10 @@ const visibleGroupBuckets = computed(() => groupedConversations.value.groups.fil
81
79
  showSearchEmpty: hasConversationSearchQuery.value && groupBucket.items.length === 0
82
80
  };
83
81
  }));
84
- const showGroupCreationPrompt = computed(
85
- () => groupsReady.value && !hasConversationSearchQuery.value && groups.value.length === 0
86
- );
87
82
  const hasConversationContent = computed(() => {
88
83
  if (hasConversationSearchQuery.value)
89
84
  return visibleGroupBuckets.value.length > 0 || groupedConversations.value.unfiled.length > 0;
90
- return showGroupCreationPrompt.value || groups.value.length > 0 || filteredConversations.value.length > 0;
85
+ return groups.value.length > 0 || filteredConversations.value.length > 0;
91
86
  });
92
87
  const shouldShowUngroupedHeader = computed(() => visibleGroupBuckets.value.length > 0);
93
88
  const ungroupedConversationLabel = computed(() => `Conversas \xB7 ${groupedConversations.value.unfiled.length}`);
@@ -96,9 +91,7 @@ const activeGroupId = computed(() => {
96
91
  return currentConversation?.groupId ?? null;
97
92
  });
98
93
  onMounted(() => {
99
- void Promise.resolve(fetchGroups()).finally(() => {
100
- groupsReady.value = true;
101
- });
94
+ void fetchGroups();
102
95
  try {
103
96
  const stored = localStorage.getItem(openGroupsStorageKey.value);
104
97
  if (stored) {
@@ -309,42 +302,6 @@ async function handleConversationDrop(event, groupId) {
309
302
  </p>
310
303
  </div>
311
304
  <div v-else flex="~ col" gap-8px>
312
- <div
313
- v-if="showGroupCreationPrompt && !hideFolderHint"
314
- mx-4px
315
- flex="~ col" gap-10px
316
- >
317
- <div h-20px flex items-center px-4px>
318
- <span text-12px font-semibold text-neutral-400 uppercase style="letter-spacing: 0">
319
- PASTAS
320
- </span>
321
- </div>
322
- <div flex="~ col" gap-6px>
323
- <div
324
- h-36px px-10px
325
- flex items-center gap-10px
326
- rounded-10px
327
- b=".5px dashed neutral-200"
328
- >
329
- <span i-ph-folder text-16px text-neutral-400 shrink-0 />
330
- <span h-10px w-120px rounded-full bg-neutral-100 />
331
- </div>
332
- <div
333
- h-36px px-10px
334
- flex items-center gap-10px
335
- rounded-10px
336
- b=".5px dashed neutral-200"
337
- >
338
- <span i-ph-folder text-16px text-neutral-400 shrink-0 />
339
- <span h-10px w-84px rounded-full bg-neutral-100 />
340
- </div>
341
- </div>
342
- <p px-4px text-14px text-neutral-500 leading-20px>
343
- Suas pastas aparecem aqui. Crie uma para começar a agrupar conversas.
344
- </p>
345
- <ChatConversationNewGroupButton label="Criar pasta" variant="empty-state" />
346
- </div>
347
-
348
305
  <div v-if="visibleGroupBuckets.length > 0" flex="~ col" gap-2px>
349
306
  <div
350
307
  v-for="groupBucket in visibleGroupBuckets"
@@ -5,7 +5,6 @@ type __VLS_Props = {
5
5
  conversations: DeepReadonly<Conversation[]>;
6
6
  activeId: string | null;
7
7
  loading?: boolean;
8
- hideFolderHint?: boolean;
9
8
  userName?: string;
10
9
  userEmail?: string;
11
10
  userImage?: string;
@@ -1,7 +1,11 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
2
- pick: (label: string) => any;
3
- }, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
4
- onPick?: ((label: string) => any) | undefined;
5
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
1
+ import type { ChatSuggestion } from '../../types.js';
2
+ type __VLS_Props = {
3
+ suggestions?: readonly ChatSuggestion[];
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
+ pick: (prompt: string) => any;
7
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ onPick?: ((prompt: string) => any) | undefined;
9
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
10
  declare const _default: typeof __VLS_export;
7
11
  export default _default;
@@ -1,31 +1,20 @@
1
1
  <script setup>
2
+ const props = defineProps({
3
+ suggestions: { type: Array, required: false }
4
+ });
2
5
  const emit = defineEmits(["pick"]);
3
- const suggestions = [
4
- { id: "s1", icon: "i-ph-file-text", label: "Resumir um documento longo" },
5
- { id: "s2", icon: "i-ph-envelope", label: "Escrever um e-mail formal" },
6
- { id: "s3", icon: "i-ph-lightbulb", label: "Brainstorm de campanha de marketing" }
7
- ];
6
+ const visibleSuggestions = computed(() => props.suggestions ?? []);
8
7
  </script>
9
8
 
10
9
  <template>
11
- <div flex="~ col">
12
- <span class="eyebrow">Sugestões</span>
13
-
14
- <div class="chip-row">
15
- <button
16
- v-for="s in suggestions"
17
- :key="s.id"
18
- type="button"
19
- class="chip"
20
- @click="emit('pick', s.label)"
21
- >
22
- <span :class="s.icon" class="chip__icon" />
23
- <span>{{ s.label }}</span>
24
- </button>
25
- </div>
26
- </div>
10
+ <TelaChatSuggestions v-if="visibleSuggestions.length">
11
+ <TelaChatSuggestion
12
+ v-for="suggestion in visibleSuggestions"
13
+ :key="suggestion.title"
14
+ :suggestion="suggestion.prompt"
15
+ @click="emit('pick', $event)"
16
+ >
17
+ {{ suggestion.title }}
18
+ </TelaChatSuggestion>
19
+ </TelaChatSuggestions>
27
20
  </template>
28
-
29
- <style scoped>
30
- .eyebrow{color:#a3a3a3;font-size:11px;font-weight:580;letter-spacing:.6px;padding:0 18px 6px;text-transform:uppercase}.chip-row{display:flex;gap:8px;overflow-x:auto;padding:4px 14px 8px;scrollbar-width:none}.chip-row::-webkit-scrollbar{display:none}.chip{align-items:center;background:#fff;border:.5px solid #d9d9d9;border-radius:999px;color:#171717;display:inline-flex;flex-shrink:0;font-size:13px;font-weight:460;gap:8px;line-height:16px;padding:9px 13px;transition:background .12s;white-space:nowrap}.chip:active{background:#f5f5f5}.chip__icon{color:#737373;font-size:16px}
31
- </style>
@@ -1,7 +1,11 @@
1
- declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
2
- pick: (label: string) => any;
3
- }, string, import("vue").PublicProps, Readonly<{}> & Readonly<{
4
- onPick?: ((label: string) => any) | undefined;
5
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
1
+ import type { ChatSuggestion } from '../../types.js';
2
+ type __VLS_Props = {
3
+ suggestions?: readonly ChatSuggestion[];
4
+ };
5
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
6
+ pick: (prompt: string) => any;
7
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
8
+ onPick?: ((prompt: string) => any) | undefined;
9
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
6
10
  declare const _default: typeof __VLS_export;
7
11
  export default _default;
@@ -4,7 +4,7 @@ import type { ConversationFile } from '../../../types/schemas/chat/files.js';
4
4
  import type { TopbarTab } from '../../../types/schemas/chat/ui.js';
5
5
  import type { WorkspaceSettingsResponse as WorkspaceSettings } from '../../../types/schemas/chat/workspace-settings.js';
6
6
  import type { TelaAgentContextFile, TelaAgentInputVariable, TelaAgentSkill } from '../../../types/schemas/integrations/tela-agent-api.js';
7
- import type { ChatActor } from '../../types.js';
7
+ import type { ChatActor, ChatSuggestion } from '../../types.js';
8
8
  type __VLS_Props = {
9
9
  currentConversation: DeepReadonly<ConversationWithMessages> | null;
10
10
  displayTitle: string;
@@ -27,8 +27,8 @@ type __VLS_Props = {
27
27
  hasPendingMessage?: boolean;
28
28
  hideSettings?: boolean;
29
29
  hideSidebar?: boolean;
30
- hideFolderHint?: boolean;
31
30
  isEditing: boolean;
31
+ suggestions?: readonly ChatSuggestion[];
32
32
  loading?: boolean;
33
33
  messages: Message[];
34
34
  showCancelButton?: boolean;
@@ -57,12 +57,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
57
57
  "update:selectedModel": (value: string | null) => any;
58
58
  } & {
59
59
  delete: () => any;
60
+ cancel: () => any;
60
61
  rename: () => any;
61
62
  duplicate: () => any;
62
63
  export: () => any;
63
64
  copyLink: () => any;
64
65
  selectConversation: (id: string) => any;
65
- cancel: () => any;
66
66
  settings: () => any;
67
67
  send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
68
68
  debug: () => any;
@@ -78,12 +78,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
78
78
  "update:workspaceSheetOpen": (value: boolean) => any;
79
79
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
80
80
  onDelete?: (() => any) | undefined;
81
+ onCancel?: (() => any) | undefined;
81
82
  onRename?: (() => any) | undefined;
82
83
  onDuplicate?: (() => any) | undefined;
83
84
  onExport?: (() => any) | undefined;
84
85
  onCopyLink?: (() => any) | undefined;
85
86
  onSelectConversation?: ((id: string) => any) | undefined;
86
- onCancel?: (() => any) | undefined;
87
87
  onSettings?: (() => any) | undefined;
88
88
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
89
89
  "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
@@ -32,8 +32,8 @@ const props = defineProps({
32
32
  hasPendingMessage: { type: Boolean, required: false },
33
33
  hideSettings: { type: Boolean, required: false },
34
34
  hideSidebar: { type: Boolean, required: false },
35
- hideFolderHint: { type: Boolean, required: false },
36
35
  isEditing: { type: Boolean, required: true },
36
+ suggestions: { type: Array, required: false },
37
37
  loading: { type: Boolean, required: false },
38
38
  messages: { type: Array, required: true },
39
39
  showCancelButton: { type: Boolean, required: false },
@@ -140,7 +140,6 @@ function startNewConversationFromOutdatedSettings() {
140
140
  :conversations="conversations"
141
141
  :active-id="activeConversationId"
142
142
  :loading="conversationsLoading"
143
- :hide-folder-hint="hideFolderHint"
144
143
  :user-name="currentUser?.name ?? void 0"
145
144
  :user-email="currentUser?.email ?? void 0"
146
145
  :user-image="currentUser?.image ?? void 0"
@@ -245,7 +244,7 @@ function startNewConversationFromOutdatedSettings() {
245
244
  />
246
245
  </div>
247
246
 
248
- <ChatMobileHomeSuggestions @pick="applySuggestion" />
247
+ <ChatMobileHomeSuggestions :suggestions="suggestions" @pick="applySuggestion" />
249
248
  </div>
250
249
 
251
250
  <div v-if="showConversationHistory" mt-auto pt-12px pb-20px b-t=".5px solid #E8E8E8">
@@ -4,7 +4,7 @@ import type { ConversationFile } from '../../../types/schemas/chat/files.js';
4
4
  import type { TopbarTab } from '../../../types/schemas/chat/ui.js';
5
5
  import type { WorkspaceSettingsResponse as WorkspaceSettings } from '../../../types/schemas/chat/workspace-settings.js';
6
6
  import type { TelaAgentContextFile, TelaAgentInputVariable, TelaAgentSkill } from '../../../types/schemas/integrations/tela-agent-api.js';
7
- import type { ChatActor } from '../../types.js';
7
+ import type { ChatActor, ChatSuggestion } from '../../types.js';
8
8
  type __VLS_Props = {
9
9
  currentConversation: DeepReadonly<ConversationWithMessages> | null;
10
10
  displayTitle: string;
@@ -27,8 +27,8 @@ type __VLS_Props = {
27
27
  hasPendingMessage?: boolean;
28
28
  hideSettings?: boolean;
29
29
  hideSidebar?: boolean;
30
- hideFolderHint?: boolean;
31
30
  isEditing: boolean;
31
+ suggestions?: readonly ChatSuggestion[];
32
32
  loading?: boolean;
33
33
  messages: Message[];
34
34
  showCancelButton?: boolean;
@@ -57,12 +57,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
57
57
  "update:selectedModel": (value: string | null) => any;
58
58
  } & {
59
59
  delete: () => any;
60
+ cancel: () => any;
60
61
  rename: () => any;
61
62
  duplicate: () => any;
62
63
  export: () => any;
63
64
  copyLink: () => any;
64
65
  selectConversation: (id: string) => any;
65
- cancel: () => any;
66
66
  settings: () => any;
67
67
  send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
68
68
  debug: () => any;
@@ -78,12 +78,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
78
78
  "update:workspaceSheetOpen": (value: boolean) => any;
79
79
  }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
80
80
  onDelete?: (() => any) | undefined;
81
+ onCancel?: (() => any) | undefined;
81
82
  onRename?: (() => any) | undefined;
82
83
  onDuplicate?: (() => any) | undefined;
83
84
  onExport?: (() => any) | undefined;
84
85
  onCopyLink?: (() => any) | undefined;
85
86
  onSelectConversation?: ((id: string) => any) | undefined;
86
- onCancel?: (() => any) | undefined;
87
87
  onSettings?: (() => any) | undefined;
88
88
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
89
89
  "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
@@ -1,6 +1,13 @@
1
+ /**
2
+ * Optional UI toggles the host passes per embed instance. All default to `false`;
3
+ * the host owns the policy (hardcoded, role-gated, or from a feature-flag provider).
4
+ */
1
5
  export type ChatFeatureConfig = {
6
+ /** Usage tab in the chat topbar, with per-conversation token and cost stats. */
2
7
  showUsageTab?: boolean;
8
+ /** Debug entry in the topbar overflow menu. */
3
9
  showDebugOption?: boolean;
10
+ /** "Stop generation" button while a response streams. */
4
11
  showCancelButton?: boolean;
5
12
  };
6
13
  export type ResolvedChatFeatureConfig = {
@@ -6,6 +6,13 @@ import type { ChatLoadingMessageMode } from './loading-messages.js';
6
6
  import type { ChatFeatureConfig } from './feature-config.js';
7
7
  import type { ChatCitationsConfig } from '../citations/types.js';
8
8
  import type { MessageFeedbackConfig, MessageFeedbackRating } from '../messages/composables/chat-feedback.js';
9
+ export type ChatEmbedVariant = 'page' | 'floating' | 'sidepanel';
10
+ export type ChatSuggestion = {
11
+ /** Short label rendered on the suggestion pill. */
12
+ title: string;
13
+ /** Full prompt written into the message input when the pill is clicked. */
14
+ prompt: string;
15
+ };
9
16
  export type ChatActor = {
10
17
  name?: string | null;
11
18
  email?: string | null;
@@ -35,9 +42,18 @@ export type ChatEmbedSharedProps = {
35
42
  conversationId?: string | null;
36
43
  /** Conversation id to open once on mount when `conversationId` is uncontrolled. */
37
44
  initialConversationId?: string | null;
38
- /** Technical scope that isolates conversation history within the current workspace and runtime. */
45
+ /**
46
+ * Technical scope that isolates conversation history within the current workspace and runtime.
47
+ * Scoped embeds only see conversations created with the same scope, and unscoped embeds only
48
+ * see unscoped ones, so adding a scope never mixes with existing workspace-level history.
49
+ * Values are trimmed, blank strings become `null`, and the server accepts 1-200 characters
50
+ * from `A-Z`, `a-z`, `0-9`, `.`, `_`, `:`, `/`, and `-`.
51
+ */
39
52
  conversationScope?: string | null;
40
- /** Initial creator filter for the sidebar conversation list. Defaults to all conversations. */
53
+ /**
54
+ * Initial creator filter for the sidebar conversation list: `'all'` (default) shows every
55
+ * conversation in scope, `'mine'` shows only those created by the current user.
56
+ */
41
57
  defaultConversationCreatorFilter?: ConversationCreatorFilter;
42
58
  /** Hide the conversation list and render only the active chat surface. */
43
59
  hideSidebar?: boolean;
@@ -46,14 +62,24 @@ export type ChatEmbedSharedProps = {
46
62
  /** Hide workspace settings actions while keeping the chat header and content unchanged. */
47
63
  hideSettings?: boolean;
48
64
  /**
49
- * Hide the empty-state folder onboarding block (PASTAS header, ghost rows, hint
50
- * text and inline create button). Folder creation stays available through the
51
- * new-group button in the sidebar header.
65
+ * Tighter spacing tuned for widget shells (floating/sidepanel). Hides the
66
+ * conversation topbar, since the widget header replaces it. Applied
67
+ * automatically by the `floating` and `sidepanel` variants.
68
+ */
69
+ compact?: boolean;
70
+ /**
71
+ * Suggestion pills rendered in the conversation empty state. Each pill shows
72
+ * its `title` and clicking it writes `prompt` into the message input. When
73
+ * omitted or empty no pills are rendered — the lib ships no defaults.
52
74
  */
53
- hideFolderHint?: boolean;
75
+ suggestions?: readonly ChatSuggestion[] | null;
54
76
  /** Custom pending-response messages shown while the assistant is working. */
55
77
  loadingMessages?: readonly string[] | null;
56
- /** How custom loading messages rotate. Defaults to ordered behavior when omitted. */
78
+ /**
79
+ * How custom loading messages rotate: `'ordered'` (default) cycles them in order,
80
+ * `'random'` picks at random. Only applies when `loadingMessages` has at least one
81
+ * non-empty message.
82
+ */
57
83
  loadingMessagesMode?: ChatLoadingMessageMode | null;
58
84
  /** Custom markdown component renderers keyed by markdown node or tag name. */
59
85
  customComponents?: Record<string, Component>;
@@ -103,4 +129,17 @@ export type TelaAgentChatEmbedProps = ChatEmbedSharedProps & {
103
129
  /** Optional UI feature toggles that are still supported in Tela agent mode. */
104
130
  features?: Partial<ChatFeatureConfig>;
105
131
  };
106
- export type MeistrariChatEmbedProps = DefaultChatEmbedProps | TelaAgentChatEmbedProps;
132
+ export type ChatEmbedVariantProps = {
133
+ /**
134
+ * Presentation shell: `'page'` (default) renders the full-page embed,
135
+ * `'floating'` renders a launcher pill with an anchored popover window, and
136
+ * `'sidepanel'` renders an always-open docked column. Widget variants render
137
+ * client-only and default to `hideSidebar`.
138
+ */
139
+ variant?: ChatEmbedVariant;
140
+ /** Floating variant only: start with the widget window open. */
141
+ defaultOpen?: boolean;
142
+ /** Floating variant only: label of the launcher pill. Defaults to `'Ask Tela'`. */
143
+ launcherLabel?: string;
144
+ };
145
+ export type MeistrariChatEmbedProps = (DefaultChatEmbedProps | TelaAgentChatEmbedProps) & ChatEmbedVariantProps;
@@ -1,4 +1,4 @@
1
1
  export declare const FILE_ICONS: Record<string, string>;
2
- export declare function getFileIcon(mimeType: string): string;
2
+ export declare function getFileIcon(mimeType?: string): string;
3
3
  export declare function getMimeIcon(mimeType?: string): string;
4
4
  export declare function getMimeLabel(mimeType?: string): string;