@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
@@ -169,69 +169,69 @@ onUnmounted(() => {
169
169
  <ChatThinkingIndicator v-if="!completed && !hasReasoning" key="thinking" />
170
170
 
171
171
  <!-- Com reasoning (loading ou completo): header clicável + steps colapsáveis -->
172
- <div v-else-if="hasReasoning" key="reasoning">
173
- <button
174
- type="button"
175
- class="group"
176
- flex
177
- items-center
178
- gap-4px
179
- px-4px
180
- pt-16px
181
- pb-8px
182
- w-full
183
- text-left
184
- transition-colors
185
- rounded-8px
186
- cursor-pointer
187
- :aria-expanded="isExpanded"
188
- :aria-busy="!completed"
189
- aria-label="Toggle reasoning steps"
190
- @click="toggleExpanded"
191
- >
192
- <span
193
- v-if="completed && showingSuccess"
194
- key="success-text"
195
- class="text-16px static-gradient-text"
196
- >
197
- Trabalho concluído
198
- </span>
199
- <div
200
- v-else-if="completed"
201
- key="completed-text"
202
- class="text-16px flex items-center gap-4px"
203
- >
204
- <span class="text-secondary group-hover:text-gray-900 transition-colors">Trabalhou por</span>
205
- <span class="text-tertiary group-hover:text-gray-900 transition-colors">{{ formattedDuration || "alguns momentos" }}</span>
206
- </div>
207
- <div
208
- v-else
209
- key="loading-text"
210
- class="text-16px flex items-center gap-8px"
172
+ <TelaCollapsible v-else-if="hasReasoning" key="reasoning" v-model:open="isExpanded">
173
+ <TelaCollapsibleTrigger as-child>
174
+ <button
175
+ type="button"
176
+ class="group"
177
+ flex
178
+ items-center
179
+ gap-4px
180
+ pt-16px
181
+ pb-8px
182
+ w-full
183
+ text-left
184
+ transition-colors
185
+ rounded-8px
186
+ cursor-pointer
187
+ :aria-busy="!completed"
188
+ aria-label="Toggle reasoning steps"
189
+ @click="userHasExpanded = true"
211
190
  >
212
191
  <span
213
- :class="hasReasoning ? 'text-gray-700' : 'running-gradient-text'"
192
+ v-if="completed && showingSuccess"
193
+ key="success-text"
194
+ class="body-14-regular static-gradient-text"
214
195
  >
215
- {{ hasReasoning ? currentStepName : loadingText }}
196
+ Trabalho concluído
216
197
  </span>
217
- <span
218
- v-if="liveFormattedDuration"
219
- class="text-12px text-gray-500 timer-mono"
198
+ <div
199
+ v-else-if="completed"
200
+ key="completed-text"
201
+ class="body-14-regular flex items-center gap-4px"
220
202
  >
221
- ({{ liveFormattedDuration }})
222
- </span>
223
- </div>
203
+ <span class="text-secondary group-hover:text-gray-900 transition-colors">Trabalhou por</span>
204
+ <span class="text-tertiary group-hover:text-gray-900 transition-colors">{{ formattedDuration || "alguns momentos" }}</span>
205
+ </div>
206
+ <div
207
+ v-else
208
+ key="loading-text"
209
+ class="body-14-regular flex items-center gap-8px"
210
+ >
211
+ <span
212
+ :class="hasReasoning ? 'text-gray-700' : 'running-gradient-text'"
213
+ >
214
+ {{ hasReasoning ? currentStepName : loadingText }}
215
+ </span>
216
+ <span
217
+ v-if="liveFormattedDuration"
218
+ class="text-12px text-gray-500 timer-mono"
219
+ >
220
+ ({{ liveFormattedDuration }})
221
+ </span>
222
+ </div>
224
223
 
225
- <div
226
- i-ph-caret-right
227
- text-12px
228
- text-gray-500
229
- group-hover:text-gray-700
230
- transition-all
231
- duration-200
232
- :class="{ 'rotate-90': isExpanded }"
233
- />
234
- </button>
224
+ <div
225
+ i-ph-caret-right
226
+ text-12px
227
+ text-gray-500
228
+ group-hover:text-gray-700
229
+ transition-all
230
+ duration-200
231
+ :class="{ 'rotate-90': isExpanded }"
232
+ />
233
+ </button>
234
+ </TelaCollapsibleTrigger>
235
235
 
236
236
  <!-- Preview mode: Always visible during loading, with gradient -->
237
237
  <div
@@ -256,17 +256,8 @@ onUnmounted(() => {
256
256
  </div>
257
257
 
258
258
  <!-- Expanded mode: Full content without gradient -->
259
- <Transition
260
- enter-active-class="transition-all duration-300 ease-out"
261
- leave-active-class="transition-all duration-200 ease-in"
262
- enter-from-class="opacity-0 -translate-y-8px max-h-0"
263
- enter-to-class="opacity-100 translate-y-0 max-h-[2000px]"
264
- leave-from-class="opacity-100 translate-y-0 max-h-[2000px]"
265
- leave-to-class="opacity-0 -translate-y-8px max-h-0"
266
- >
259
+ <TelaCollapsibleContent>
267
260
  <div
268
- v-if="isExpanded"
269
- overflow-hidden
270
261
  border="~ 0.5 default rounded-16px"
271
262
  mb-16px
272
263
  >
@@ -276,8 +267,8 @@ onUnmounted(() => {
276
267
  :completed="completed"
277
268
  />
278
269
  </div>
279
- </Transition>
280
- </div>
270
+ </TelaCollapsibleContent>
271
+ </TelaCollapsible>
281
272
  </div>
282
273
  </template>
283
274
 
@@ -52,13 +52,7 @@ onUnmounted(() => {
52
52
  </script>
53
53
 
54
54
  <template>
55
- <div flex justify-start pl-16px py-16px>
56
- <span class="running-gradient-text" body-16-regular>
57
- {{ currentText }}
58
- </span>
59
- </div>
55
+ <TelaChatTextShimmer class="body-16-regular">
56
+ {{ currentText }}
57
+ </TelaChatTextShimmer>
60
58
  </template>
61
-
62
- <style scoped>
63
- .running-gradient-text{background:linear-gradient(90deg,#9da2aa,#f4f5f7 50%,#9da2aa);background-clip:text;-webkit-background-clip:text;background-size:200% 100%;-webkit-text-fill-color:transparent;animation:gradientAnimation 1.5s linear infinite}@keyframes gradientAnimation{0%{background-position:200% 50%}to{background-position:0 50%}}
64
- </style>
@@ -29,17 +29,8 @@ const isOutputCode = computed(() => {
29
29
  </script>
30
30
 
31
31
  <template>
32
- <div class="bg-subtle rounded-16px border border-gray-200">
33
- <!-- Header -->
34
- <div class="px-16px py-16px flex items-center justify-between">
35
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
36
- Bash
37
- </h3>
38
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
39
- </div>
40
-
41
- <!-- Content -->
42
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
32
+ <TelaChatWidgetCard title="Bash" :status-variant="statusVariant" :status-label="statusLabel">
33
+ <div v-if="toolResult" class="space-y-16px">
43
34
  <!-- Command section -->
44
35
  <div>
45
36
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -82,5 +73,5 @@ const isOutputCode = computed(() => {
82
73
  </div>
83
74
  </div>
84
75
  </div>
85
- </div>
76
+ </TelaChatWidgetCard>
86
77
  </template>
@@ -29,17 +29,8 @@ const isOutputCode = computed(() => {
29
29
  </script>
30
30
 
31
31
  <template>
32
- <div class="bg-subtle rounded-16px border border-gray-200">
33
- <!-- Header -->
34
- <div class="px-16px py-16px flex items-center justify-between">
35
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary">
36
- {{ skillName }}
37
- </h3>
38
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
39
- </div>
40
-
41
- <!-- Content -->
42
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
32
+ <TelaChatWidgetCard :title="skillName" :status-variant="statusVariant" :status-label="statusLabel">
33
+ <div v-if="toolResult" class="space-y-16px">
43
34
  <!-- Result -->
44
35
  <div>
45
36
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -70,5 +61,5 @@ const isOutputCode = computed(() => {
70
61
  </div>
71
62
  </div>
72
63
  </div>
73
- </div>
64
+ </TelaChatWidgetCard>
74
65
  </template>
@@ -82,17 +82,8 @@ const isEmptyMessage = computed(() => {
82
82
  </script>
83
83
 
84
84
  <template>
85
- <div class="bg-subtle rounded-16px border border-gray-200">
86
- <!-- Header -->
87
- <div class="px-16px py-16px flex items-center justify-between">
88
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
89
- {{ name }}
90
- </h3>
91
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
92
- </div>
93
-
94
- <!-- Content -->
95
- <div v-if="hasContent" class="px-16px pb-16px space-y-16px">
85
+ <TelaChatWidgetCard :title="name" :status-variant="statusVariant" :status-label="statusLabel">
86
+ <div v-if="hasContent" class="space-y-16px">
96
87
  <!-- Parameters section -->
97
88
  <div v-if="input && Object.keys(input).length > 0">
98
89
  <!-- Special handling for TodoWrite tool -->
@@ -326,7 +317,7 @@ const isEmptyMessage = computed(() => {
326
317
  </div>
327
318
  </div>
328
319
  </div>
329
- </div>
320
+ </TelaChatWidgetCard>
330
321
  </template>
331
322
 
332
323
  <style scoped>
@@ -120,23 +120,13 @@ function highlightMatch(content) {
120
120
  </script>
121
121
 
122
122
  <template>
123
- <div class="bg-subtle rounded-16px border border-gray-200">
124
- <!-- Header -->
125
- <div class="px-16px py-16px flex items-center justify-between">
126
- <div class="flex-1 min-w-0">
127
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
128
- Grep
129
- </h3>
130
- <p class="text-12px text-secondary truncate mt-2px">
131
- <span class="font-mono">{{ pattern.length > 30 ? `${pattern.slice(0, 30)}...` : pattern }}</span>
132
- <span class="opacity-60"> em {{ shortPath }}</span>
133
- </p>
134
- </div>
135
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
136
- </div>
123
+ <TelaChatWidgetCard title="Grep" :status-variant="statusVariant" :status-label="statusLabel ?? ''">
124
+ <template #subtitle>
125
+ <span class="font-mono">{{ pattern.length > 30 ? `${pattern.slice(0, 30)}...` : pattern }}</span>
126
+ <span class="opacity-60"> em {{ shortPath }}</span>
127
+ </template>
137
128
 
138
- <!-- Content -->
139
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
129
+ <div v-if="toolResult" class="space-y-16px">
140
130
  <!-- Search info -->
141
131
  <div>
142
132
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -251,7 +241,7 @@ function highlightMatch(content) {
251
241
  </div>
252
242
  </div>
253
243
  </div>
254
- </div>
244
+ </TelaChatWidgetCard>
255
245
  </template>
256
246
 
257
247
  <style scoped>
@@ -111,23 +111,13 @@ const isContentCode = computed(() => {
111
111
  </script>
112
112
 
113
113
  <template>
114
- <div class="bg-subtle rounded-16px border border-gray-200">
115
- <!-- Header -->
116
- <div class="px-16px py-16px flex items-center justify-between">
117
- <div class="flex-1 min-w-0">
118
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
119
- Read
120
- </h3>
121
- <p class="text-12px text-secondary truncate mt-2px">
122
- {{ fileName }}
123
- <span v-if="parentDir" class="opacity-60">em {{ parentDir }}</span>
124
- </p>
125
- </div>
126
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
127
- </div>
114
+ <TelaChatWidgetCard title="Read" :status-variant="statusVariant" :status-label="statusLabel ?? ''">
115
+ <template #subtitle>
116
+ {{ fileName }}
117
+ <span v-if="parentDir" class="opacity-60">em {{ parentDir }}</span>
118
+ </template>
128
119
 
129
- <!-- Content -->
130
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
120
+ <div v-if="toolResult" class="space-y-16px">
131
121
  <!-- File path section -->
132
122
  <div>
133
123
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -187,7 +177,7 @@ const isContentCode = computed(() => {
187
177
  </div>
188
178
  </div>
189
179
  </div>
190
- </div>
180
+ </TelaChatWidgetCard>
191
181
  </template>
192
182
 
193
183
  <style scoped>
@@ -37,17 +37,8 @@ const argsValue = computed(() => {
37
37
  </script>
38
38
 
39
39
  <template>
40
- <div class="bg-subtle rounded-16px border border-gray-200">
41
- <!-- Header -->
42
- <div class="px-16px py-16px flex items-center justify-between">
43
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
44
- {{ skillName }}
45
- </h3>
46
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
47
- </div>
48
-
49
- <!-- Content -->
50
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
40
+ <TelaChatWidgetCard :title="skillName" :status-variant="statusVariant" :status-label="statusLabel">
41
+ <template v-if="toolResult">
51
42
  <!-- Arguments section -->
52
43
  <div v-if="hasArgs">
53
44
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -89,6 +80,6 @@ const argsValue = computed(() => {
89
80
  </p>
90
81
  </div>
91
82
  </div>
92
- </div>
93
- </div>
83
+ </template>
84
+ </TelaChatWidgetCard>
94
85
  </template>
@@ -22,30 +22,19 @@ const title = computed(() => {
22
22
  </script>
23
23
 
24
24
  <template>
25
- <div class="bg-subtle rounded-16px border border-gray-200">
26
- <!-- Header -->
27
- <div class="px-16px py-16px flex items-center justify-between">
28
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
29
- {{ title }}
30
- </h3>
31
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
32
- </div>
33
-
34
- <!-- Content -->
35
- <div class="px-16px pb-16px">
36
- <div class="bg-white rounded-xl border-0.5px border-gray-200 px-3 py-2">
37
- <div class="reasoning-markdown text-14px text-primary">
38
- <ClientOnly>
39
- <AppMarkdownRender
40
- :content="content"
41
- :render-code-blocks-as-pre="true"
42
- :typewriter="false"
43
- />
44
- </ClientOnly>
45
- </div>
25
+ <TelaChatWidgetCard :title="title" :status-variant="statusVariant" :status-label="statusLabel">
26
+ <div class="bg-white rounded-xl border-0.5px border-gray-200 px-3 py-2">
27
+ <div class="reasoning-markdown text-14px text-primary">
28
+ <ClientOnly>
29
+ <AppMarkdownRender
30
+ :content="content"
31
+ :render-code-blocks-as-pre="true"
32
+ :typewriter="false"
33
+ />
34
+ </ClientOnly>
46
35
  </div>
47
36
  </div>
48
- </div>
37
+ </TelaChatWidgetCard>
49
38
  </template>
50
39
 
51
40
  <style scoped>
@@ -42,49 +42,22 @@ const sources = computed(() => {
42
42
  </script>
43
43
 
44
44
  <template>
45
- <div class="bg-subtle rounded-16px border border-gray-200">
46
- <!-- Header -->
47
- <div class="px-16px py-16px flex items-center justify-between">
48
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
49
- WebSearch
50
- </h3>
51
- <TelaStatus :variant="statusVariant" :label="statusLabel" />
52
- </div>
53
-
54
- <!-- Content -->
55
- <div v-if="toolResult" class="px-16px pb-16px space-y-16px">
45
+ <TelaChatWidgetCard title="WebSearch" :status-variant="statusVariant" :status-label="statusLabel">
46
+ <template v-if="toolResult">
56
47
  <!-- Sources list -->
57
48
  <div v-if="sources.length > 0">
58
49
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
59
50
  Fontes
60
51
  </div>
61
- <div class="bg-white rounded-xl border-0.5px border-gray-200 px-3 py-2">
62
- <div class="flex flex-col gap-6px">
63
- <a
64
- v-for="source in sources"
65
- :key="source.url"
66
- :href="source.url"
67
- target="_blank"
68
- rel="noopener noreferrer"
69
- class="flex items-center gap-8px py-8px border-b border-gray-100 last:border-0 hover:bg-gray-50 transition-colors group"
70
- >
71
- <img
72
- :src="`https://www.google.com/s2/favicons?domain=${source.domain}&sz=32`"
73
- :alt="source.domain"
74
- class="w-16px h-16px rounded-4px"
75
- >
76
- <div class="flex-1 min-w-0">
77
- <div class="text-14px font-medium text-primary truncate group-hover:text-blue-700">
78
- {{ source.title }}
79
- </div>
80
- <div class="text-12px text-gray-500 truncate">
81
- {{ source.domain }}
82
- </div>
83
- </div>
84
- <div class="i-ph-arrow-square-out text-14px text-gray-400 group-hover:text-blue-500" />
85
- </a>
86
- </div>
87
- </div>
52
+ <TelaChatWidgetSources>
53
+ <TelaChatWidgetSource
54
+ v-for="source in sources"
55
+ :key="source.url"
56
+ :title="source.title || source.url"
57
+ :domain="source.domain"
58
+ :href="source.url"
59
+ />
60
+ </TelaChatWidgetSources>
88
61
  </div>
89
62
 
90
63
  <!-- Result -->
@@ -116,6 +89,6 @@ const sources = computed(() => {
116
89
  </p>
117
90
  </div>
118
91
  </div>
119
- </div>
120
- </div>
92
+ </template>
93
+ </TelaChatWidgetCard>
121
94
  </template>
@@ -335,86 +335,73 @@ const displayName = computed(() => {
335
335
  </script>
336
336
 
337
337
  <template>
338
- <div class="bg-subtle rounded-16px border border-gray-200">
339
- <!-- Header -->
340
- <div class="px-16px py-16px flex items-center justify-between">
341
- <div class="flex-1 min-w-0">
342
- <h3 class="text-16px font-580 leading-20px tracking-[-0.3px] text-primary truncate">
343
- Consulta de Dados
344
- </h3>
345
- <p v-if="displayName !== 'Workstation'" class="text-12px text-secondary truncate mt-2px">
346
- {{ displayName }}
347
- </p>
348
- </div>
349
- <TelaStatus
350
- :variant="statusVariant"
351
- :label="statusLabel"
352
- :is-icon-animated="!toolResult"
353
- />
354
- </div>
338
+ <TelaChatWidgetCard
339
+ title="Consulta de Dados"
340
+ :status-variant="statusVariant"
341
+ :status-label="statusLabel ?? ''"
342
+ :is-icon-animated="!toolResult"
343
+ >
344
+ <template v-if="displayName !== 'Workstation'" #subtitle>
345
+ {{ displayName }}
346
+ </template>
355
347
 
356
348
  <!-- Filters preview (when collapsed) -->
357
349
  <div
358
350
  v-if="!expanded && canExpand && (formattedFilters || formattedOutputQuery)"
359
- class="px-16px pb-12px"
351
+ class="flex flex-wrap items-center gap-6px"
360
352
  >
361
- <div class="flex flex-wrap items-center gap-6px">
362
- <template v-if="formattedFilters">
363
- <span
364
- v-for="filter in formattedFilters.slice(0, 3)"
365
- :key="filter"
366
- class="text-11px px-8px py-3px rounded-6px bg-gray-100 text-gray-600"
367
- >
368
- {{ filter }}
369
- </span>
370
- </template>
371
- <template v-if="formattedOutputQuery">
372
- <span
373
- v-for="query in formattedOutputQuery.slice(0, 3)"
374
- :key="query"
375
- class="text-11px px-8px py-3px rounded-6px bg-blue-100 text-blue-700"
376
- >
377
- {{ query }}
378
- </span>
379
- </template>
353
+ <template v-if="formattedFilters">
380
354
  <span
381
- v-if="(formattedFilters?.length || 0) + (formattedOutputQuery?.length || 0) > 3"
382
- class="text-11px text-gray-400"
355
+ v-for="filter in formattedFilters.slice(0, 3)"
356
+ :key="filter"
357
+ class="text-11px px-8px py-3px rounded-6px bg-gray-100 text-gray-600"
383
358
  >
384
- +{{ (formattedFilters?.length || 0) + (formattedOutputQuery?.length || 0) - 3 }} mais
359
+ {{ filter }}
385
360
  </span>
386
- </div>
361
+ </template>
362
+ <template v-if="formattedOutputQuery">
363
+ <span
364
+ v-for="query in formattedOutputQuery.slice(0, 3)"
365
+ :key="query"
366
+ class="text-11px px-8px py-3px rounded-6px bg-blue-100 text-blue-700"
367
+ >
368
+ {{ query }}
369
+ </span>
370
+ </template>
371
+ <span
372
+ v-if="(formattedFilters?.length || 0) + (formattedOutputQuery?.length || 0) > 3"
373
+ class="text-11px text-gray-400"
374
+ >
375
+ +{{ (formattedFilters?.length || 0) + (formattedOutputQuery?.length || 0) - 3 }} mais
376
+ </span>
387
377
  </div>
388
378
 
389
379
  <!-- Launch message (when only have launching output) -->
390
- <div v-if="toolResult && isLaunchMessage" class="px-16px pb-16px">
391
- <div class="bg-blue-50 rounded-xl border-0.5px border-blue-200 px-16px py-12px">
392
- <div class="flex items-center gap-8px">
393
- <div class="i-ph-clock text-16px text-blue-600 animate-pulse" />
394
- <p class="text-13px text-blue-700 m-0">
395
- Aguardando resultados da consulta...
396
- </p>
397
- </div>
380
+ <div v-if="toolResult && isLaunchMessage" class="bg-blue-50 rounded-xl border-0.5px border-blue-200 px-16px py-12px">
381
+ <div class="flex items-center gap-8px">
382
+ <div class="i-ph-clock text-16px text-blue-600 animate-pulse" />
383
+ <p class="text-13px text-blue-700 m-0">
384
+ Aguardando resultados da consulta...
385
+ </p>
398
386
  </div>
399
387
  </div>
400
388
 
401
389
  <!-- Expand/Collapse button -->
402
- <div v-if="toolResult && !isLaunchMessage" class="px-16px pb-12px">
403
- <button
404
- type="button"
405
- class="w-full flex items-center justify-center gap-6px px-12px py-8px text-13px font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-8px transition-colors"
406
- @click="expanded = !expanded"
407
- >
408
- <span>{{ expanded ? "Ocultar detalhes" : "Ver detalhes" }}</span>
409
- <div
410
- class="i-ph-caret-down text-12px transition-transform"
411
- :class="expanded && 'rotate-180'"
412
- />
413
- </button>
414
- </div>
390
+ <button
391
+ v-if="toolResult && !isLaunchMessage"
392
+ type="button"
393
+ class="w-full flex items-center justify-center gap-6px px-12px py-8px text-13px font-medium text-gray-600 hover:text-gray-900 hover:bg-gray-50 rounded-8px transition-colors"
394
+ @click="expanded = !expanded"
395
+ >
396
+ <span>{{ expanded ? "Ocultar detalhes" : "Ver detalhes" }}</span>
397
+ <div
398
+ class="i-ph-caret-down text-12px transition-transform"
399
+ :class="expanded && 'rotate-180'"
400
+ />
401
+ </button>
415
402
 
416
403
  <!-- Expanded content -->
417
- <div v-if="expanded && toolResult && !isLaunchMessage" class="px-16px pb-16px space-y-16px">
404
+ <template v-if="expanded && toolResult && !isLaunchMessage">
418
405
  <!-- Filters section -->
419
406
  <div v-if="formattedFilters || formattedOutputQuery">
420
407
  <div class="text-14px font-580 leading-16px tracking-[-0.15px] text-gray-700 mb-2">
@@ -548,6 +535,6 @@ const displayName = computed(() => {
548
535
  <pre class="text-14px text-primary whitespace-pre-wrap break-words m-0">{{ toolResult.output }}</pre>
549
536
  </div>
550
537
  </div>
551
- </div>
552
- </div>
538
+ </template>
539
+ </TelaChatWidgetCard>
553
540
  </template>