@meistrari/chat-nuxt 3.3.2 → 3.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (29) hide show
  1. package/dist/module.json +1 -1
  2. package/dist/runtime/conversations/composables/conversations.d.ts +4 -1
  3. package/dist/runtime/conversations/composables/conversations.js +31 -3
  4. package/dist/runtime/embed/components/chat-embed-inner.vue +28 -2
  5. package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +9 -2
  6. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue +2 -0
  7. package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +9 -2
  8. package/dist/runtime/messages/components/chat-message-input.d.vue.ts +10 -3
  9. package/dist/runtime/messages/components/chat-message-input.vue +6 -0
  10. package/dist/runtime/messages/components/chat-message-input.vue.d.ts +10 -3
  11. package/dist/runtime/messages/components/chat-model-selector.d.vue.ts +14 -0
  12. package/dist/runtime/messages/components/chat-model-selector.vue +56 -0
  13. package/dist/runtime/messages/components/chat-model-selector.vue.d.ts +14 -0
  14. package/dist/runtime/messages/composables/chat.d.ts +2 -0
  15. package/dist/runtime/messages/composables/chat.js +22 -0
  16. package/dist/runtime/shared/components/icons/anthropic.vue +1 -1
  17. package/dist/runtime/shared/components/icons/gemini.d.vue.ts +3 -0
  18. package/dist/runtime/shared/components/icons/gemini.vue +3 -0
  19. package/dist/runtime/shared/components/icons/gemini.vue.d.ts +3 -0
  20. package/dist/runtime/shared/components/icons/openai.d.vue.ts +3 -0
  21. package/dist/runtime/shared/components/icons/openai.vue +3 -0
  22. package/dist/runtime/shared/components/icons/openai.vue.d.ts +3 -0
  23. package/dist/runtime/types/schemas/chat/conversations.d.ts +10 -1
  24. package/dist/runtime/types/schemas/chat/conversations.js +3 -1
  25. package/dist/runtime/types/schemas/chat/models.d.ts +4 -6
  26. package/dist/runtime/types/schemas/chat/models.js +3 -5
  27. package/dist/runtime/types/schemas/chat/ui.d.ts +39 -16
  28. package/dist/runtime/types/schemas/chat/ui.js +5 -5
  29. package/package.json +1 -1
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meistrari/chat-nuxt",
3
3
  "configKey": "chatNuxt",
4
- "version": "3.3.2",
4
+ "version": "3.4.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -8,9 +8,12 @@ export declare function useConversations(): {
8
8
  fetchConversations: (options?: {
9
9
  force?: boolean;
10
10
  }) => Promise<void>;
11
- createConversation: () => Promise<Conversation | null>;
11
+ createConversation: (input?: {
12
+ model?: string | null;
13
+ }) => Promise<Conversation | null>;
12
14
  deleteConversation: (id: string) => Promise<boolean>;
13
15
  renameConversation: (id: string, title: string) => Promise<boolean>;
16
+ updateConversationModel: (id: string, model: string | null) => Promise<boolean>;
14
17
  moveConversationToGroup: (id: string, groupId: string | null) => Promise<boolean>;
15
18
  duplicateConversation: (id: string) => Promise<ConversationWithMessages | null>;
16
19
  conversationCreatorFilter: any;
@@ -291,7 +291,7 @@ export function useConversations() {
291
291
  setBucketValue(loadingBuckets, requestScope, false);
292
292
  }
293
293
  };
294
- const createConversation = async () => {
294
+ const createConversation = async (input) => {
295
295
  error.value = null;
296
296
  const requestRuntimeScope = runtimeScope.value;
297
297
  const metadataSnapshot = snapshotConversationMetadata(requestRuntimeScope);
@@ -303,7 +303,7 @@ export function useConversations() {
303
303
  userId: authUser.value?.id ?? "",
304
304
  title: "Nova conversa",
305
305
  threadSessionId: null,
306
- model: null,
306
+ model: input?.model ?? null,
307
307
  appliedSettingsAt: null,
308
308
  appliedSettingsSnapshot: null,
309
309
  telaAgentId: embedConfig?.telaAgentId.value ?? null,
@@ -318,7 +318,8 @@ export function useConversations() {
318
318
  const conversation = await $fetch(
319
319
  chatApi.path("/conversations"),
320
320
  chatApi.withChatHeaders({
321
- method: "POST"
321
+ method: "POST",
322
+ ...input?.model ? { body: { model: input.model } } : {}
322
323
  })
323
324
  );
324
325
  upsertConversationInLoadedBuckets(conversation, requestRuntimeScope, optimisticConversation.id);
@@ -440,6 +441,32 @@ export function useConversations() {
440
441
  return false;
441
442
  }
442
443
  };
444
+ const updateConversationModel = async (id, model) => {
445
+ error.value = null;
446
+ const requestRuntimeScope = runtimeScope.value;
447
+ const affectedScopes = activeAndLoadedRuntimeConversationScopes(requestRuntimeScope);
448
+ const conversationSnapshot = snapshotConversationBuckets(affectedScopes);
449
+ const conversation = findConversationInLoadedBuckets(id, requestRuntimeScope);
450
+ if (conversation)
451
+ updateConversationInLoadedBuckets({ ...conversation, model, updatedAt: /* @__PURE__ */ new Date() }, requestRuntimeScope);
452
+ try {
453
+ const updated = await $fetch(
454
+ chatApi.path(`/conversations/${id}`),
455
+ chatApi.withChatHeaders({
456
+ method: "PATCH",
457
+ body: { model }
458
+ })
459
+ );
460
+ updateConversationInLoadedBuckets(updated, requestRuntimeScope);
461
+ return true;
462
+ } catch (err) {
463
+ restoreConversationBuckets(conversationSnapshot, id);
464
+ const message = err instanceof Error ? err.message : "Erro ao atualizar modelo da conversa";
465
+ error.value = message;
466
+ Sentry.captureException(err);
467
+ return false;
468
+ }
469
+ };
443
470
  const duplicateConversation = async (id) => {
444
471
  error.value = null;
445
472
  const statusToast = useStatusToast();
@@ -476,6 +503,7 @@ export function useConversations() {
476
503
  createConversation,
477
504
  deleteConversation,
478
505
  renameConversation,
506
+ updateConversationModel,
479
507
  moveConversationToGroup,
480
508
  duplicateConversation,
481
509
  conversationCreatorFilter,
@@ -52,7 +52,7 @@ const chatAction = useChatAction();
52
52
  const { user: authUser, activeOrganization, logout } = useChatAuth();
53
53
  const { getMember, getMemberImage } = useWorkspaceMembers();
54
54
  const statusToast = useStatusToast();
55
- const { conversations, loading: conversationsLoading, fetchConversations, createConversation, deleteConversation, renameConversation, duplicateConversation, moveConversationToGroup, updateConversationInList } = useConversations();
55
+ const { conversations, loading: conversationsLoading, fetchConversations, createConversation, deleteConversation, renameConversation, updateConversationModel, duplicateConversation, moveConversationToGroup, updateConversationInList } = useConversations();
56
56
  const { settings: workspaceSettingsState, fetchSettings } = useWorkspaceSettings();
57
57
  const { metadata: telaAgentMetadata, loading: telaAgentMetadataLoading, fetchAgentMetadata } = useTelaAgentMetadata();
58
58
  const isTelaAgentMode = computed(() => !!embedConfig?.telaAgentId.value);
@@ -100,6 +100,8 @@ const {
100
100
  hasPendingMessage,
101
101
  loadConversation,
102
102
  setConversation,
103
+ setConversationModel,
104
+ pendingModelSelection,
103
105
  sendMessage,
104
106
  retryMessage,
105
107
  cancelConversation,
@@ -108,6 +110,21 @@ const {
108
110
  } = useChat();
109
111
  const conversationIdRef = computed(() => currentConversation.value?.id ?? null);
110
112
  const { total, files: conversationFiles } = useConversationFiles(conversationIdRef);
113
+ const selectedModel = computed({
114
+ get: () => currentConversation.value ? currentConversation.value.model : pendingModelSelection.value,
115
+ set: (value) => {
116
+ pendingModelSelection.value = value;
117
+ const conversation = currentConversation.value;
118
+ if (conversation && conversation.model !== value) {
119
+ const previousModel = conversation.model;
120
+ setConversationModel(value);
121
+ void updateConversationModel(conversation.id, value).then((updated) => {
122
+ if (!updated && currentConversation.value?.id === conversation.id && currentConversation.value.model === value)
123
+ setConversationModel(previousModel);
124
+ });
125
+ }
126
+ }
127
+ });
111
128
  const filesCount = computed(() => total.value);
112
129
  const hasMessages = computed(() => messages.value.length > 0);
113
130
  const mobilePreviewFile = computed(() => {
@@ -296,7 +313,9 @@ const conversationCreator = computed(
296
313
  async function handleSend(content, files, agentInputs) {
297
314
  let createdConversationId = null;
298
315
  if (!activeConversationId.value || !currentConversation.value) {
299
- const conversation = await createConversation();
316
+ const conversation = await createConversation(
317
+ selectedModel.value ? { model: selectedModel.value } : void 0
318
+ );
300
319
  if (!conversation)
301
320
  return;
302
321
  const groupId = pendingConversationGroupId.value;
@@ -520,6 +539,7 @@ async function handleDelete() {
520
539
  v-if="isMobile"
521
540
  v-model:drawer-open="drawerOpen"
522
541
  v-model:edit-title="editTitle"
542
+ v-model:selected-model="selectedModel"
523
543
  v-model:workspace-sheet-open="workspaceSheetOpen"
524
544
  :current-conversation="currentConversation"
525
545
  :display-title="displayTitle"
@@ -573,6 +593,7 @@ async function handleDelete() {
573
593
  loading
574
594
  />
575
595
  <ChatMessageInput
596
+ v-model:selected-model="selectedModel"
576
597
  :disabled="true"
577
598
  :agent-input-schema="visibleTelaAgentInputSchema"
578
599
  :agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
@@ -595,6 +616,7 @@ async function handleDelete() {
595
616
  </div>
596
617
  <ChatMessageInput
597
618
  ref="messageInputRef"
619
+ v-model:selected-model="selectedModel"
598
620
  :disabled="hasPendingMessage"
599
621
  :loading="hasPendingMessage"
600
622
  :creator-name="currentUser?.name ?? void 0"
@@ -619,6 +641,7 @@ async function handleDelete() {
619
641
  />
620
642
  <ChatMessageInput
621
643
  ref="messageInputRef"
644
+ v-model:selected-model="selectedModel"
622
645
  :disabled="hasPendingMessage"
623
646
  :loading="hasPendingMessage"
624
647
  :creator-name="currentUser?.name ?? void 0"
@@ -718,6 +741,7 @@ async function handleDelete() {
718
741
  loading
719
742
  />
720
743
  <ChatMessageInput
744
+ v-model:selected-model="selectedModel"
721
745
  :disabled="true"
722
746
  :agent-input-schema="visibleTelaAgentInputSchema"
723
747
  :agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
@@ -740,6 +764,7 @@ async function handleDelete() {
740
764
  </div>
741
765
  <ChatMessageInput
742
766
  ref="messageInputRef"
767
+ v-model:selected-model="selectedModel"
743
768
  :disabled="hasPendingMessage"
744
769
  :loading="hasPendingMessage"
745
770
  :creator-name="currentUser?.name ?? void 0"
@@ -765,6 +790,7 @@ async function handleDelete() {
765
790
  />
766
791
  <ChatMessageInput
767
792
  ref="messageInputRef"
793
+ v-model:selected-model="selectedModel"
768
794
  :disabled="hasPendingMessage"
769
795
  :loading="hasPendingMessage"
770
796
  :creator-name="currentUser?.name ?? void 0"
@@ -38,6 +38,10 @@ type __VLS_Props = {
38
38
  workspaceSettings?: DeepReadonly<WorkspaceSettings> | null;
39
39
  workspaceSheetOpen: boolean;
40
40
  };
41
+ type __VLS_ModelProps = {
42
+ 'selectedModel'?: string | null;
43
+ };
44
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
41
45
  declare var __VLS_54: {}, __VLS_99: {}, __VLS_101: {};
42
46
  type __VLS_Slots = {} & {
43
47
  loading?: (props: typeof __VLS_54) => any;
@@ -46,7 +50,9 @@ type __VLS_Slots = {} & {
46
50
  } & {
47
51
  default?: (props: typeof __VLS_101) => any;
48
52
  };
49
- declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
53
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
54
+ "update:selectedModel": (value: string | null) => any;
55
+ } & {
50
56
  delete: () => any;
51
57
  rename: () => any;
52
58
  duplicate: () => any;
@@ -67,7 +73,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
67
73
  "update:drawerOpen": (value: boolean) => any;
68
74
  "update:editTitle": (value: string) => any;
69
75
  "update:workspaceSheetOpen": (value: boolean) => any;
70
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
76
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
71
77
  onDelete?: (() => any) | undefined;
72
78
  onRename?: (() => any) | undefined;
73
79
  onDuplicate?: (() => any) | undefined;
@@ -77,6 +83,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
77
83
  onCancel?: (() => any) | undefined;
78
84
  onSettings?: (() => any) | undefined;
79
85
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
86
+ "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
80
87
  onDebug?: (() => any) | undefined;
81
88
  onTabChange?: ((tab: TopbarTab) => any) | undefined;
82
89
  onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
@@ -44,6 +44,7 @@ const props = defineProps({
44
44
  workspaceSheetOpen: { type: Boolean, required: true }
45
45
  });
46
46
  const emit = defineEmits(["cancel", "cancelEditing", "copyLink", "debug", "delete", "dismissOutdatedBanner", "duplicate", "export", "newConversation", "rename", "saveTitle", "selectConversation", "send", "settings", "signout", "switchWorkspace", "tabChange", "update:drawerOpen", "update:editTitle", "update:workspaceSheetOpen"]);
47
+ const selectedModel = defineModel("selectedModel", { type: [String, null], ...{ default: null } });
47
48
  const renameInputRef = ref(null);
48
49
  const homeInputRef = ref(null);
49
50
  const outdatedSettingsSheetOpen = ref(false);
@@ -220,6 +221,7 @@ function startNewConversationFromOutdatedSettings() {
220
221
  <div px-14px pb-12px>
221
222
  <ChatMessageInput
222
223
  ref="homeInputRef"
224
+ v-model:selected-model="selectedModel"
223
225
  :disabled="hasPendingMessage"
224
226
  :loading="hasPendingMessage"
225
227
  :creator-name="currentUser?.name ?? void 0"
@@ -38,6 +38,10 @@ type __VLS_Props = {
38
38
  workspaceSettings?: DeepReadonly<WorkspaceSettings> | null;
39
39
  workspaceSheetOpen: boolean;
40
40
  };
41
+ type __VLS_ModelProps = {
42
+ 'selectedModel'?: string | null;
43
+ };
44
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
41
45
  declare var __VLS_54: {}, __VLS_99: {}, __VLS_101: {};
42
46
  type __VLS_Slots = {} & {
43
47
  loading?: (props: typeof __VLS_54) => any;
@@ -46,7 +50,9 @@ type __VLS_Slots = {} & {
46
50
  } & {
47
51
  default?: (props: typeof __VLS_101) => any;
48
52
  };
49
- declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
53
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
54
+ "update:selectedModel": (value: string | null) => any;
55
+ } & {
50
56
  delete: () => any;
51
57
  rename: () => any;
52
58
  duplicate: () => any;
@@ -67,7 +73,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
67
73
  "update:drawerOpen": (value: boolean) => any;
68
74
  "update:editTitle": (value: string) => any;
69
75
  "update:workspaceSheetOpen": (value: boolean) => any;
70
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
76
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
71
77
  onDelete?: (() => any) | undefined;
72
78
  onRename?: (() => any) | undefined;
73
79
  onDuplicate?: (() => any) | undefined;
@@ -77,6 +83,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
77
83
  onCancel?: (() => any) | undefined;
78
84
  onSettings?: (() => any) | undefined;
79
85
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
86
+ "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
80
87
  onDebug?: (() => any) | undefined;
81
88
  onTabChange?: ((tab: TopbarTab) => any) | undefined;
82
89
  onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
@@ -20,15 +20,22 @@ type __VLS_Props = {
20
20
  };
21
21
  declare function addFiles(files: File[], inputName?: string): void;
22
22
  declare function setDraft(text: string): void;
23
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
23
+ type __VLS_ModelProps = {
24
+ 'selectedModel'?: string | null;
25
+ };
26
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
27
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
24
28
  addFiles: typeof addFiles;
25
29
  setDraft: typeof setDraft;
26
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
30
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
+ "update:selectedModel": (value: string | null) => any;
32
+ } & {
27
33
  cancel: () => any;
28
34
  send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
29
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
35
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
30
36
  onCancel?: (() => any) | undefined;
31
37
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
38
+ "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
32
39
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
40
  declare const _default: typeof __VLS_export;
34
41
  export default _default;
@@ -22,6 +22,7 @@ const props = defineProps({
22
22
  showCancelButton: { type: Boolean, required: false }
23
23
  });
24
24
  const emit = defineEmits(["send", "cancel"]);
25
+ const selectedModel = defineModel("selectedModel", { type: [String, null], ...{ default: null } });
25
26
  const { uploadFiles, uploading, uploadError } = useFileUpload();
26
27
  const isCancelEnabled = computed(() => props.showCancelButton === true);
27
28
  const content = ref("");
@@ -633,6 +634,11 @@ defineExpose({
633
634
  @blur="handleBlur"
634
635
  />
635
636
  <div flex items-center gap-8px>
637
+ <ChatModelSelector
638
+ v-model="selectedModel"
639
+ :disabled="isLocked"
640
+ @click.stop
641
+ />
636
642
  <div flex-1 />
637
643
  <TelaTooltip :content="pendingFiles.length >= MAX_FILES ? 'Limite de arquivos atingido' : 'Anexar arquivo'" side="top">
638
644
  <TelaIconButton
@@ -20,15 +20,22 @@ type __VLS_Props = {
20
20
  };
21
21
  declare function addFiles(files: File[], inputName?: string): void;
22
22
  declare function setDraft(text: string): void;
23
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
23
+ type __VLS_ModelProps = {
24
+ 'selectedModel'?: string | null;
25
+ };
26
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
27
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
24
28
  addFiles: typeof addFiles;
25
29
  setDraft: typeof setDraft;
26
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
30
+ }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
31
+ "update:selectedModel": (value: string | null) => any;
32
+ } & {
27
33
  cancel: () => any;
28
34
  send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
29
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
35
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
30
36
  onCancel?: (() => any) | undefined;
31
37
  onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
38
+ "onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
32
39
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
40
  declare const _default: typeof __VLS_export;
34
41
  export default _default;
@@ -0,0 +1,14 @@
1
+ type __VLS_Props = {
2
+ disabled?: boolean;
3
+ };
4
+ type __VLS_ModelProps = {
5
+ modelValue?: string | null;
6
+ };
7
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "update:modelValue": (value: string | null) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -0,0 +1,56 @@
1
+ <script setup>
2
+ import { chatModelOptions } from "../../types/schemas/chat/ui.js";
3
+ import AnthropicIcon from "../../shared/components/icons/anthropic.vue";
4
+ import GeminiIcon from "../../shared/components/icons/gemini.vue";
5
+ import OpenAiIcon from "../../shared/components/icons/openai.vue";
6
+ defineProps({
7
+ disabled: { type: Boolean, required: false }
8
+ });
9
+ const model = defineModel({ type: [String, null], ...{ default: null } });
10
+ const providerIcons = {
11
+ Anthropic: AnthropicIcon,
12
+ OpenAI: OpenAiIcon,
13
+ Google: GeminiIcon
14
+ };
15
+ const options = chatModelOptions.map((option) => ({
16
+ value: option.value,
17
+ label: option.label,
18
+ description: option.description,
19
+ group: option.provider,
20
+ icon: providerIcons[option.provider],
21
+ cost: option.cost,
22
+ maxInputTokens: option.maxInputTokens,
23
+ maxOutputTokens: option.maxOutputTokens,
24
+ isMultiModal: option.isMultiModal,
25
+ tabs: [...option.tabs]
26
+ }));
27
+ const tabLabels = {
28
+ all: "Todos",
29
+ advanced: "Avan\xE7ados",
30
+ cheap: "Econ\xF4micos",
31
+ multimodal: "Multimodal"
32
+ };
33
+ function getTabLabel(tab) {
34
+ return tabLabels[tab] ?? tab;
35
+ }
36
+ </script>
37
+
38
+ <template>
39
+ <TelaCombobox
40
+ :model-value="model ?? void 0"
41
+ :options="options"
42
+ :class="disabled && 'opacity-50 pointer-events-none'"
43
+ placeholder="Modelo"
44
+ input-placeholder="Buscar modelo..."
45
+ :get-tab-label="getTabLabel"
46
+ trigger-class="border-none!"
47
+ label-class="!text-14px !leading-18px !font-normal -tracking-0.01em! !text-gray-500"
48
+ icon-class="scale-110 mr-1px !text-gray-500"
49
+ label-item-class="!text-gray-500"
50
+ @update:model-value="model = $event ?? null"
51
+ />
52
+ </template>
53
+
54
+ <style>
55
+ [role=option] svg{color:#6b7280}
56
+ </style>
@@ -0,0 +1,14 @@
1
+ type __VLS_Props = {
2
+ disabled?: boolean;
3
+ };
4
+ type __VLS_ModelProps = {
5
+ modelValue?: string | null;
6
+ };
7
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
8
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
9
+ "update:modelValue": (value: string | null) => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
11
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
12
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
13
+ declare const _default: typeof __VLS_export;
14
+ export default _default;
@@ -14,6 +14,8 @@ export declare function useChat(): {
14
14
  animatedTitle: any;
15
15
  loadConversation: (id: string) => Promise<void>;
16
16
  setConversation: (conv: Conversation | ConversationWithMessages) => void;
17
+ setConversationModel: (model: string | null) => void;
18
+ pendingModelSelection: any;
17
19
  sendMessage: (content: string, files?: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[]) => Promise<Message | null>;
18
20
  retryMessage: (messageId: string) => Promise<boolean>;
19
21
  cancelConversation: () => Promise<boolean>;
@@ -1,5 +1,6 @@
1
1
  import { useChatAuth } from "#chat-auth";
2
2
  import * as Sentry from "@sentry/nuxt";
3
+ import { defaultChatModel } from "../../types/schemas/chat/models.js";
3
4
  import {
4
5
  createReasoningCache,
5
6
  resolveReasoningDisplayMessages
@@ -117,6 +118,25 @@ export function useChat() {
117
118
  pollGeneration++;
118
119
  endPolling();
119
120
  }
121
+ const pendingModelBuckets = useState("chat-pending-model-selection", () => ({}));
122
+ const pendingModelSelection = computed({
123
+ get: () => {
124
+ const buckets = pendingModelBuckets.value;
125
+ return chatScope.value in buckets ? buckets[chatScope.value] ?? null : defaultChatModel;
126
+ },
127
+ set: (value) => {
128
+ pendingModelBuckets.value = {
129
+ ...pendingModelBuckets.value,
130
+ [chatScope.value]: value
131
+ };
132
+ }
133
+ });
134
+ const setConversationModel = (model) => {
135
+ const conversation = currentConversation.value;
136
+ if (!conversation || conversation.model === model)
137
+ return;
138
+ currentConversation.value = { ...conversation, model };
139
+ };
120
140
  const setConversation = (conv) => {
121
141
  const conversationMessages = "messages" in conv ? conv.messages : [];
122
142
  currentConversation.value = { ...conv, messages: conversationMessages };
@@ -394,6 +414,8 @@ export function useChat() {
394
414
  animatedTitle: readonly(animatedTitle),
395
415
  loadConversation,
396
416
  setConversation,
417
+ setConversationModel,
418
+ pendingModelSelection,
397
419
  sendMessage,
398
420
  retryMessage,
399
421
  cancelConversation,
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <svg viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
2
+ <svg viewBox="0 0 24 24" width="16" height="16" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
3
3
  <path d="M13.827 3.52h3.603L24 20h-3.603l-6.57-16.48zM6.396 3.52L0 20h3.603l1.351-3.384h6.827l1.351 3.384h3.603L10.119 3.52H6.396zm.663 10.155 2.33-5.879 2.33 5.879H7.06z" />
4
4
  </svg>
5
5
  </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <svg width="16" height="16" fill="currentColor" fill-rule="evenodd" viewBox="-2 -2 28 28" xmlns="http://www.w3.org/2000/svg"><path d="M12 24A14.304 14.304 0 000 12 14.304 14.304 0 0012 0a14.305 14.305 0 0012 12 14.305 14.305 0 00-12 12" /></svg>
3
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,3 @@
1
+ <template>
2
+ <svg width="16" height="16" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M18.8545 10.5474C19.0334 10.0086 19.0953 9.43791 19.036 8.87334C18.9767 8.30877 18.7977 7.76335 18.5107 7.27352C18.0854 6.53313 17.4359 5.94695 16.6559 5.59949C15.876 5.25202 15.0058 5.16122 14.1709 5.34018C13.6966 4.81256 13.0917 4.41903 12.4172 4.19912C11.7426 3.97922 11.0221 3.94068 10.3279 4.08737C9.63377 4.23406 8.99043 4.56082 8.46252 5.03484C7.93461 5.50885 7.54072 6.11343 7.32041 6.78785C6.76419 6.90191 6.23872 7.13337 5.77912 7.46678C5.31951 7.80018 4.93637 8.22784 4.65528 8.72118C4.2253 9.46033 4.04153 10.3171 4.13054 11.1675C4.21955 12.018 4.57672 12.8181 5.15041 13.4522C4.97086 13.9907 4.90836 14.5614 4.96711 15.1259C5.02586 15.6905 5.2045 16.2361 5.49108 16.726C5.91697 17.4667 6.56703 18.053 7.34755 18.4005C8.12808 18.7479 8.99877 18.8386 9.83415 18.6594C10.211 19.0838 10.674 19.4229 11.1924 19.6541C11.7107 19.8852 12.2724 20.0032 12.8399 20C13.6956 20.0008 14.5295 19.7296 15.2211 19.2256C15.9127 18.7217 16.4263 18.011 16.6877 17.1961C17.2439 17.0819 17.7693 16.8503 18.2289 16.5169C18.6885 16.1835 19.0716 15.7559 19.3529 15.2627C19.7778 14.5247 19.9584 13.6711 19.8689 12.8242C19.7794 11.9773 19.4243 11.1803 18.8545 10.5474ZM12.8399 18.9528C12.139 18.9539 11.4601 18.7082 10.9223 18.2589L11.0169 18.2053L14.2024 16.3665C14.2817 16.32 14.3475 16.2537 14.3934 16.1741C14.4393 16.0944 14.4637 16.0042 14.4642 15.9123V11.421L15.8109 12.2001C15.8175 12.2035 15.8233 12.2084 15.8277 12.2144C15.8321 12.2204 15.835 12.2274 15.8362 12.2348V15.9565C15.8345 16.7507 15.5183 17.5118 14.9567 18.0734C14.3952 18.6349 13.634 18.9511 12.8399 18.9528ZM6.39941 16.2025C6.04793 15.5956 5.92173 14.8842 6.04301 14.1934L6.13768 14.2502L9.32635 16.089C9.40525 16.1353 9.49507 16.1597 9.58655 16.1597C9.67803 16.1597 9.76785 16.1353 9.84675 16.089L13.7419 13.8433V15.3982C13.7416 15.4063 13.7394 15.4142 13.7356 15.4213C13.7317 15.4284 13.7264 15.4345 13.7198 15.4392L10.4933 17.3001C9.8047 17.6968 8.98685 17.804 8.21929 17.5982C7.45173 17.3924 6.7972 16.8905 6.39941 16.2025ZM5.56048 9.26372C5.9144 8.6529 6.47304 8.187 7.13748 7.94852V11.7333C7.13628 11.8248 7.15964 11.9148 7.20513 11.9942C7.25062 12.0735 7.31656 12.1392 7.39608 12.1843L11.2723 14.4205L9.92561 15.1995C9.91833 15.2034 9.9102 15.2054 9.90195 15.2054C9.8937 15.2054 9.88557 15.2034 9.87828 15.1995L6.65808 13.3418C5.97079 12.9435 5.46938 12.2889 5.26366 11.5216C5.05794 10.7543 5.16467 9.93676 5.56048 9.24798V9.26372ZM16.6247 11.8342L12.7358 9.57598L14.0794 8.79998C14.0867 8.79611 14.0948 8.79409 14.1031 8.79409C14.1113 8.79409 14.1195 8.79611 14.1267 8.79998L17.3469 10.6608C17.8393 10.945 18.2407 11.3633 18.5043 11.8669C18.7678 12.3706 18.8826 12.9388 18.8354 13.5053C18.7881 14.0718 18.5806 14.6131 18.2372 15.0661C17.8938 15.5191 17.4286 15.8651 16.8959 16.0637V12.2788C16.8932 12.1876 16.8667 12.0986 16.8191 12.0206C16.7715 11.9427 16.7046 11.8785 16.6247 11.8342ZM17.9651 9.81885L17.8705 9.76205L14.6881 7.90752C14.6088 7.86093 14.5184 7.83637 14.4263 7.83637C14.3343 7.83637 14.2439 7.86093 14.1645 7.90752L10.2726 10.1531V8.59825C10.2718 8.59034 10.2731 8.58236 10.2764 8.57515C10.2798 8.56793 10.285 8.56175 10.2915 8.55725L13.5117 6.69952C14.0053 6.4152 14.5696 6.27728 15.1386 6.30189C15.7077 6.3265 16.258 6.51263 16.7251 6.83851C17.1923 7.16438 17.557 7.61653 17.7766 8.14207C17.9962 8.66761 18.0616 9.24482 17.9652 9.80618L17.9651 9.81885ZM9.53761 12.5753L8.19095 11.7994C8.18421 11.7954 8.17845 11.7899 8.17407 11.7834C8.16969 11.7768 8.16681 11.7694 8.16561 11.7616V8.04945C8.16636 7.47997 8.3292 6.92246 8.63512 6.44212C8.94103 5.96177 9.37736 5.57844 9.89311 5.33694C10.4089 5.09544 10.9827 5.00576 11.5475 5.07837C12.1124 5.15098 12.6449 5.38289 13.0827 5.74698L12.9881 5.80065L9.80261 7.63932C9.72333 7.68582 9.65751 7.75214 9.61161 7.83177C9.56571 7.9114 9.54131 8.0016 9.54081 8.09352L9.53761 12.5753ZM10.2693 10.9984L12.004 9.99852L13.7419 10.9984V12.998L12.0103 13.9978L10.2725 12.998L10.2693 10.9984Z" /></svg>
3
+ </template>
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -210,11 +210,20 @@ export declare const conversationWithMessagesSchema: z.ZodObject<{
210
210
  }, z.core.$strip>;
211
211
  export type ConversationWithMessages = z.infer<typeof conversationWithMessagesSchema>;
212
212
  export declare const createConversationRequestSchema: z.ZodObject<{
213
- model: z.ZodOptional<z.ZodNullable<z.ZodString>>;
213
+ model: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
214
+ "claude-opus-4-8": "claude-opus-4-8";
215
+ "claude-sonnet-5": "claude-sonnet-5";
216
+ "claude-haiku-4-5": "claude-haiku-4-5";
217
+ }>>>;
214
218
  }, z.core.$strict>;
215
219
  export type CreateConversationRequest = z.infer<typeof createConversationRequestSchema>;
216
220
  export declare const updateConversationRequestSchema: z.ZodObject<{
217
221
  title: z.ZodOptional<z.ZodString>;
222
+ model: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
223
+ "claude-opus-4-8": "claude-opus-4-8";
224
+ "claude-sonnet-5": "claude-sonnet-5";
225
+ "claude-haiku-4-5": "claude-haiku-4-5";
226
+ }>>>;
218
227
  }, z.core.$strict>;
219
228
  export type UpdateConversationRequest = z.infer<typeof updateConversationRequestSchema>;
220
229
  export declare const moveConversationRequestSchema: z.ZodObject<{
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { messageFileSchema } from './files';
3
+ import { chatModelSchema } from './models';
3
4
  import { conversationCreatorFilterSchema, messageRoleSchema, messageStatusSchema, } from './primitives';
4
5
  import { resolvedWorkspaceSettingsSchema } from './workspace-settings';
5
6
  export const conversationSchema = z.object({
@@ -50,10 +51,11 @@ export const conversationWithMessagesSchema = conversationSchema.extend({
50
51
  messages: z.array(messageSchema),
51
52
  });
52
53
  export const createConversationRequestSchema = z.strictObject({
53
- model: z.string().nullable().optional(),
54
+ model: chatModelSchema.nullable().optional(),
54
55
  });
55
56
  export const updateConversationRequestSchema = z.strictObject({
56
57
  title: z.string().optional(),
58
+ model: chatModelSchema.nullable().optional(),
57
59
  });
58
60
  export const moveConversationRequestSchema = z.object({
59
61
  groupId: z.string().nullable(),
@@ -1,12 +1,10 @@
1
1
  import { z } from 'zod';
2
- export declare const chatModelIds: readonly ["claude-sonnet-4-5", "claude-sonnet-4-6", "claude-haiku-4-5", "claude-opus-4-5", "claude-opus-4-6"];
2
+ export declare const chatModelIds: readonly ["claude-opus-4-8", "claude-sonnet-5", "claude-haiku-4-5"];
3
3
  export declare const chatModelSchema: z.ZodEnum<{
4
- "claude-sonnet-4-5": "claude-sonnet-4-5";
5
- "claude-sonnet-4-6": "claude-sonnet-4-6";
4
+ "claude-opus-4-8": "claude-opus-4-8";
5
+ "claude-sonnet-5": "claude-sonnet-5";
6
6
  "claude-haiku-4-5": "claude-haiku-4-5";
7
- "claude-opus-4-5": "claude-opus-4-5";
8
- "claude-opus-4-6": "claude-opus-4-6";
9
7
  }>;
10
8
  export type ChatModel = z.infer<typeof chatModelSchema>;
11
- export declare const defaultChatModel = "claude-sonnet-4-6";
9
+ export declare const defaultChatModel = "claude-opus-4-8";
12
10
  export declare function isValidChatModel(value: unknown): value is ChatModel;
@@ -1,13 +1,11 @@
1
1
  import { z } from 'zod';
2
2
  export const chatModelIds = [
3
- 'claude-sonnet-4-5',
4
- 'claude-sonnet-4-6',
3
+ 'claude-opus-4-8',
4
+ 'claude-sonnet-5',
5
5
  'claude-haiku-4-5',
6
- 'claude-opus-4-5',
7
- 'claude-opus-4-6',
8
6
  ];
9
7
  export const chatModelSchema = z.enum(chatModelIds);
10
- export const defaultChatModel = 'claude-sonnet-4-6';
8
+ export const defaultChatModel = 'claude-opus-4-8';
11
9
  export function isValidChatModel(value) {
12
10
  return typeof value === 'string' && chatModelIds.includes(value);
13
11
  }
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import type { ChatModel } from './models';
2
3
  export declare const conversationCreatorFilterOptions: readonly [{
3
4
  readonly label: "Todas";
4
5
  readonly value: "all";
@@ -6,26 +7,48 @@ export declare const conversationCreatorFilterOptions: readonly [{
6
7
  readonly label: "Minhas";
7
8
  readonly value: "mine";
8
9
  }];
10
+ export type ChatModelProvider = 'Anthropic' | 'OpenAI' | 'Google';
11
+ export type ChatModelOption = {
12
+ value: ChatModel;
13
+ label: string;
14
+ description: string;
15
+ provider: ChatModelProvider;
16
+ cost: number;
17
+ maxInputTokens: number;
18
+ maxOutputTokens: number;
19
+ isMultiModal: boolean;
20
+ tabs: readonly string[];
21
+ };
9
22
  export declare const chatModelOptions: readonly [{
10
- readonly value: "claude-sonnet-4-5";
11
- readonly label: "Sonnet 4.5";
12
- readonly description: "High performant agent for complex tasks";
23
+ readonly value: "claude-opus-4-8";
24
+ readonly label: "Claude 4.8 Opus";
25
+ readonly description: "Agente de ponta para tarefas complexas";
26
+ readonly provider: "Anthropic";
27
+ readonly cost: 4;
28
+ readonly maxInputTokens: 1000000;
29
+ readonly maxOutputTokens: 128000;
30
+ readonly isMultiModal: true;
31
+ readonly tabs: readonly ["all", "advanced", "multimodal"];
13
32
  }, {
14
- readonly value: "claude-sonnet-4-6";
15
- readonly label: "Sonnet 4.6";
16
- readonly description: "Fast and intelligent agent";
33
+ readonly value: "claude-sonnet-5";
34
+ readonly label: "Claude Sonnet 5";
35
+ readonly description: "Agente rápido e inteligente de nova geração";
36
+ readonly provider: "Anthropic";
37
+ readonly cost: 4;
38
+ readonly maxInputTokens: 1000000;
39
+ readonly maxOutputTokens: 64000;
40
+ readonly isMultiModal: true;
41
+ readonly tabs: readonly ["all", "advanced", "multimodal"];
17
42
  }, {
18
43
  readonly value: "claude-haiku-4-5";
19
- readonly label: "Haiku 4.5";
20
- readonly description: "Fast and efficient agent for simple tasks";
21
- }, {
22
- readonly value: "claude-opus-4-5";
23
- readonly label: "Opus 4.5";
24
- readonly description: "Most powerful agent for complex tasks";
25
- }, {
26
- readonly value: "claude-opus-4-6";
27
- readonly label: "Opus 4.6";
28
- readonly description: "Top-tier agent with extended thinking";
44
+ readonly label: "Claude 4.5 Haiku";
45
+ readonly description: "Agente rápido e eficiente para tarefas simples";
46
+ readonly provider: "Anthropic";
47
+ readonly cost: 3;
48
+ readonly maxInputTokens: 200000;
49
+ readonly maxOutputTokens: 64000;
50
+ readonly isMultiModal: true;
51
+ readonly tabs: readonly ["all", "cheap", "multimodal"];
29
52
  }];
30
53
  export declare const topbarTabs: readonly ["chat", "files", "usage"];
31
54
  export declare const topbarTabSchema: z.ZodEnum<{
@@ -3,12 +3,12 @@ export const conversationCreatorFilterOptions = [
3
3
  { label: 'Todas', value: 'all' },
4
4
  { label: 'Minhas', value: 'mine' },
5
5
  ];
6
+ // Metadata follows the agent model catalog on the Tela platform
7
+ // (packages/application/composables/model.ts), curated to the models this app offers.
6
8
  export const chatModelOptions = [
7
- { value: 'claude-sonnet-4-5', label: 'Sonnet 4.5', description: 'High performant agent for complex tasks' },
8
- { value: 'claude-sonnet-4-6', label: 'Sonnet 4.6', description: 'Fast and intelligent agent' },
9
- { value: 'claude-haiku-4-5', label: 'Haiku 4.5', description: 'Fast and efficient agent for simple tasks' },
10
- { value: 'claude-opus-4-5', label: 'Opus 4.5', description: 'Most powerful agent for complex tasks' },
11
- { value: 'claude-opus-4-6', label: 'Opus 4.6', description: 'Top-tier agent with extended thinking' },
9
+ { value: 'claude-opus-4-8', label: 'Claude 4.8 Opus', description: 'Agente de ponta para tarefas complexas', provider: 'Anthropic', cost: 4, maxInputTokens: 1_000_000, maxOutputTokens: 128_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
10
+ { value: 'claude-sonnet-5', label: 'Claude Sonnet 5', description: 'Agente rápido e inteligente de nova geração', provider: 'Anthropic', cost: 4, maxInputTokens: 1_000_000, maxOutputTokens: 64_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
11
+ { value: 'claude-haiku-4-5', label: 'Claude 4.5 Haiku', description: 'Agente rápido e eficiente para tarefas simples', provider: 'Anthropic', cost: 3, maxInputTokens: 200_000, maxOutputTokens: 64_000, isMultiModal: true, tabs: ['all', 'cheap', 'multimodal'] },
12
12
  ];
13
13
  export const topbarTabs = ['chat', 'files', 'usage'];
14
14
  export const topbarTabSchema = z.enum(topbarTabs);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/chat-nuxt",
3
- "version": "3.3.2",
3
+ "version": "3.4.0",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {