@meistrari/chat-nuxt 3.9.2 → 3.11.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 (106) 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 +442 -174
  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 -4
  41. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +4 -4
  42. package/dist/runtime/embed/composables/use-agent-wake.d.ts +23 -0
  43. package/dist/runtime/embed/composables/use-agent-wake.js +182 -0
  44. package/dist/runtime/embed/feature-config.d.ts +7 -0
  45. package/dist/runtime/embed/feature-config.js +2 -1
  46. package/dist/runtime/embed/loading-messages.d.ts +16 -0
  47. package/dist/runtime/embed/loading-messages.js +10 -0
  48. package/dist/runtime/embed/types.d.ts +47 -8
  49. package/dist/runtime/files/icons.d.ts +1 -1
  50. package/dist/runtime/files/icons.js +1 -1
  51. package/dist/runtime/messages/components/chat-mention-dropdown.d.vue.ts +6 -1
  52. package/dist/runtime/messages/components/chat-mention-dropdown.vue +46 -22
  53. package/dist/runtime/messages/components/chat-mention-dropdown.vue.d.ts +6 -1
  54. package/dist/runtime/messages/components/chat-message-bubble.d.vue.ts +10 -1
  55. package/dist/runtime/messages/components/chat-message-bubble.vue +69 -76
  56. package/dist/runtime/messages/components/chat-message-bubble.vue.d.ts +10 -1
  57. package/dist/runtime/messages/components/chat-message-feedback.vue +25 -229
  58. package/dist/runtime/messages/components/chat-message-input.vue +176 -134
  59. package/dist/runtime/messages/components/chat-message-list.d.vue.ts +12 -1
  60. package/dist/runtime/messages/components/chat-message-list.vue +37 -24
  61. package/dist/runtime/messages/components/chat-message-list.vue.d.ts +12 -1
  62. package/dist/runtime/messages/components/chat-model-selector.vue +10 -22
  63. package/dist/runtime/messages/components/reasoning/chat-reasoning-message.vue +2 -3
  64. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.d.vue.ts +2 -1
  65. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +69 -77
  66. package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue.d.ts +2 -1
  67. package/dist/runtime/messages/components/reasoning/chat-thinking-indicator.vue +3 -9
  68. package/dist/runtime/messages/components/widgets/chat-bash-widget.vue +3 -12
  69. package/dist/runtime/messages/components/widgets/chat-doc-sdk-widget.vue +3 -12
  70. package/dist/runtime/messages/components/widgets/chat-generic-tool-widget.vue +3 -12
  71. package/dist/runtime/messages/components/widgets/chat-grep-widget.vue +7 -17
  72. package/dist/runtime/messages/components/widgets/chat-read-widget.vue +7 -17
  73. package/dist/runtime/messages/components/widgets/chat-tela-skill-widget.vue +4 -13
  74. package/dist/runtime/messages/components/widgets/chat-thinking-widget.vue +11 -22
  75. package/dist/runtime/messages/components/widgets/chat-web-search-widget.vue +13 -40
  76. package/dist/runtime/messages/components/widgets/chat-workstation-query-widget.vue +52 -65
  77. package/dist/runtime/messages/components/widgets/chat-write-widget.vue +8 -18
  78. package/dist/runtime/messages/composables/chat.d.ts +8 -2
  79. package/dist/runtime/messages/composables/chat.js +180 -25
  80. package/dist/runtime/messages/composables/mention-autocomplete.js +4 -0
  81. package/dist/runtime/messages/composables/use-direct-stream.d.ts +41 -0
  82. package/dist/runtime/messages/composables/use-direct-stream.js +263 -0
  83. package/dist/runtime/messages/message-state.js +1 -0
  84. package/dist/runtime/messages/reasoning.d.ts +7 -0
  85. package/dist/runtime/messages/reasoning.js +5 -0
  86. package/dist/runtime/public/files/generic.svg +2 -5
  87. package/dist/runtime/public/files/image.svg +2 -1
  88. package/dist/runtime/types/embed.d.ts +1 -1
  89. package/dist/runtime/types/schemas/chat/conversations.d.ts +4 -0
  90. package/dist/runtime/types/schemas/chat/conversations.js +3 -0
  91. package/dist/runtime/types/schemas/chat/messages.d.ts +43 -0
  92. package/dist/runtime/types/schemas/chat/messages.js +31 -0
  93. package/dist/runtime/types/schemas/chat/models.d.ts +3 -2
  94. package/dist/runtime/types/schemas/chat/models.js +2 -1
  95. package/dist/runtime/types/schemas/chat/ui.d.ts +10 -0
  96. package/dist/runtime/types/schemas/chat/ui.js +1 -0
  97. package/dist/runtime/types/schemas/integrations/tela-agent-api.d.ts +35 -0
  98. package/dist/runtime/types/schemas/integrations/tela-agent-api.js +17 -0
  99. package/dist/types.d.mts +1 -1
  100. package/package.json +5 -4
  101. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.d.vue.ts +0 -23
  102. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue +0 -75
  103. package/dist/runtime/conversations/components/chat-conversation-new-group-popover-content.vue.d.ts +0 -23
  104. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.d.vue.ts +0 -37
  105. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue +0 -125
  106. package/dist/runtime/messages/components/reasoning/chat-reasoning-step-item.vue.d.ts +0 -37
@@ -1,4 +1,5 @@
1
1
  <script setup>
2
+ import { resolveDisplayedReasoning } from "../../reasoning";
2
3
  import { resolveToolTitle } from "../../tool-registry";
3
4
  import ChatReasoningSteps from "./chat-reasoning-steps.vue";
4
5
  const props = defineProps({
@@ -6,7 +7,8 @@ const props = defineProps({
6
7
  completed: { type: Boolean, required: true },
7
8
  animate: { type: Boolean, required: false },
8
9
  createdAt: { type: [Date, String], required: true },
9
- updatedAt: { type: [Date, String, null], required: false }
10
+ updatedAt: { type: [Date, String, null], required: false },
11
+ preparingSteps: { type: [Array, null], required: false }
10
12
  });
11
13
  const SUCCESS_ANIMATION_DURATION_MS = 1e3;
12
14
  const DOT_ANIMATION_INTERVAL_MS = 500;
@@ -23,11 +25,10 @@ let dotInterval;
23
25
  let timerInterval;
24
26
  const storageKey = computed(() => `reasoning-timer-${new Date(props.createdAt).getTime()}`);
25
27
  const showGradient = computed(() => !props.completed && !isExpanded.value);
26
- const groupedReasoning = computed(() => {
27
- if (!props.reasoningData || !Array.isArray(props.reasoningData))
28
- return [];
29
- return props.reasoningData;
30
- });
28
+ const displayedReasoning = computed(
29
+ () => resolveDisplayedReasoning(props.reasoningData, props.preparingSteps)
30
+ );
31
+ const groupedReasoning = computed(() => displayedReasoning.value);
31
32
  const hasReasoning = computed(() => groupedReasoning.value.length > 0);
32
33
  const lastStep = computed(() => {
33
34
  const steps = groupedReasoning.value;
@@ -169,69 +170,69 @@ onUnmounted(() => {
169
170
  <ChatThinkingIndicator v-if="!completed && !hasReasoning" key="thinking" />
170
171
 
171
172
  <!-- 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"
173
+ <TelaCollapsible v-else-if="hasReasoning" key="reasoning" v-model:open="isExpanded">
174
+ <TelaCollapsibleTrigger as-child>
175
+ <button
176
+ type="button"
177
+ class="group"
178
+ flex
179
+ items-center
180
+ gap-4px
181
+ pt-16px
182
+ pb-8px
183
+ w-full
184
+ text-left
185
+ transition-colors
186
+ rounded-8px
187
+ cursor-pointer
188
+ :aria-busy="!completed"
189
+ aria-label="Toggle reasoning steps"
190
+ @click="userHasExpanded = true"
211
191
  >
212
192
  <span
213
- :class="hasReasoning ? 'text-gray-700' : 'running-gradient-text'"
193
+ v-if="completed && showingSuccess"
194
+ key="success-text"
195
+ class="body-14-regular static-gradient-text"
214
196
  >
215
- {{ hasReasoning ? currentStepName : loadingText }}
197
+ Trabalho concluído
216
198
  </span>
217
- <span
218
- v-if="liveFormattedDuration"
219
- class="text-12px text-gray-500 timer-mono"
199
+ <div
200
+ v-else-if="completed"
201
+ key="completed-text"
202
+ class="body-14-regular flex items-center gap-4px"
220
203
  >
221
- ({{ liveFormattedDuration }})
222
- </span>
223
- </div>
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="body-14-regular flex items-center gap-8px"
211
+ >
212
+ <span
213
+ :class="hasReasoning ? 'text-gray-700' : 'running-gradient-text'"
214
+ >
215
+ {{ hasReasoning ? currentStepName : loadingText }}
216
+ </span>
217
+ <span
218
+ v-if="liveFormattedDuration"
219
+ class="text-12px text-gray-500 timer-mono"
220
+ >
221
+ ({{ liveFormattedDuration }})
222
+ </span>
223
+ </div>
224
224
 
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>
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>
235
+ </TelaCollapsibleTrigger>
235
236
 
236
237
  <!-- Preview mode: Always visible during loading, with gradient -->
237
238
  <div
@@ -247,7 +248,7 @@ onUnmounted(() => {
247
248
  :class="{ 'with-gradient': showGradient }"
248
249
  >
249
250
  <ChatReasoningSteps
250
- :reasoning-data="reasoningData"
251
+ :reasoning-data="displayedReasoning"
251
252
  :animate="animate && !completed"
252
253
  :completed="completed"
253
254
  :is-preview-mode="true"
@@ -256,28 +257,19 @@ onUnmounted(() => {
256
257
  </div>
257
258
 
258
259
  <!-- 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
- >
260
+ <TelaCollapsibleContent>
267
261
  <div
268
- v-if="isExpanded"
269
- overflow-hidden
270
262
  border="~ 0.5 default rounded-16px"
271
263
  mb-16px
272
264
  >
273
265
  <ChatReasoningSteps
274
- :reasoning-data="reasoningData"
266
+ :reasoning-data="displayedReasoning"
275
267
  :animate="animate && !completed"
276
268
  :completed="completed"
277
269
  />
278
270
  </div>
279
- </Transition>
280
- </div>
271
+ </TelaCollapsibleContent>
272
+ </TelaCollapsible>
281
273
  </div>
282
274
  </template>
283
275
 
@@ -1,10 +1,11 @@
1
- import type { ReasoningStep } from '../../reasoning.js';
1
+ import { type ReasoningStep } from '../../reasoning.js';
2
2
  type __VLS_Props = {
3
3
  reasoningData: ReasoningStep[];
4
4
  completed: boolean;
5
5
  animate?: boolean;
6
6
  createdAt: Date | string;
7
7
  updatedAt?: Date | string | null;
8
+ preparingSteps?: readonly string[] | null;
8
9
  };
9
10
  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>;
10
11
  declare const _default: typeof __VLS_export;
@@ -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>