@meistrari/chat-nuxt 3.0.0 → 3.2.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 (55) hide show
  1. package/README.md +99 -14
  2. package/dist/module.d.mts +1 -1
  3. package/dist/module.json +1 -1
  4. package/dist/runtime/embed/components/chat-configuration-modal.vue +59 -176
  5. package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +13 -2
  6. package/dist/runtime/embed/components/chat-embed-inner.vue +22 -3
  7. package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +13 -2
  8. package/dist/runtime/embed/components/chat-embed.d.vue.ts +11 -1
  9. package/dist/runtime/embed/components/chat-embed.vue +7 -1
  10. package/dist/runtime/embed/components/chat-embed.vue.d.ts +11 -1
  11. package/dist/runtime/embed/components/configuration/chat-configuration-agent-tab.d.vue.ts +13 -0
  12. package/dist/runtime/embed/components/configuration/chat-configuration-agent-tab.vue +167 -0
  13. package/dist/runtime/embed/components/configuration/chat-configuration-agent-tab.vue.d.ts +13 -0
  14. package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +9 -4
  15. package/dist/runtime/embed/components/meistrari-chat-embed.vue +14 -2
  16. package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +9 -4
  17. package/dist/runtime/embed/types.d.ts +14 -0
  18. package/dist/runtime/files/file-limits.d.ts +2 -0
  19. package/dist/runtime/files/file-limits.js +2 -0
  20. package/dist/runtime/messages/components/chat-context-config.vue +2 -2
  21. package/dist/runtime/messages/components/chat-message-input.vue +1 -1
  22. package/dist/runtime/messages/composables/chat.js +4 -3
  23. package/dist/runtime/shared/chat-api-error.d.ts +1 -0
  24. package/dist/runtime/shared/chat-api-error.js +5 -0
  25. package/dist/runtime/types/embed.d.ts +1 -1
  26. package/dist/runtime/types/schemas/chat/workspace-agent.d.ts +33 -0
  27. package/dist/runtime/types/schemas/chat/workspace-agent.js +12 -0
  28. package/dist/runtime/types/schemas/index.d.ts +1 -0
  29. package/dist/runtime/types/schemas/index.js +1 -0
  30. package/dist/runtime/types/workspace-settings.d.ts +1 -1
  31. package/dist/runtime/workspace/composables/github-skills-callback.js +1 -1
  32. package/dist/runtime/workspace/composables/workspace-agent.d.ts +8 -0
  33. package/dist/runtime/workspace/composables/workspace-agent.js +89 -0
  34. package/dist/types.d.mts +1 -1
  35. package/package.json +1 -1
  36. package/dist/runtime/embed/components/configuration/chat-configuration-context-files-tab.d.vue.ts +0 -22
  37. package/dist/runtime/embed/components/configuration/chat-configuration-context-files-tab.vue +0 -133
  38. package/dist/runtime/embed/components/configuration/chat-configuration-context-files-tab.vue.d.ts +0 -22
  39. package/dist/runtime/embed/components/configuration/chat-configuration-external-skills-tab.d.vue.ts +0 -32
  40. package/dist/runtime/embed/components/configuration/chat-configuration-external-skills-tab.vue +0 -222
  41. package/dist/runtime/embed/components/configuration/chat-configuration-external-skills-tab.vue.d.ts +0 -32
  42. package/dist/runtime/embed/components/configuration/chat-configuration-personalization-tab.d.vue.ts +0 -10
  43. package/dist/runtime/embed/components/configuration/chat-configuration-personalization-tab.vue +0 -37
  44. package/dist/runtime/embed/components/configuration/chat-configuration-personalization-tab.vue.d.ts +0 -10
  45. package/dist/runtime/embed/components/configuration/chat-configuration-tela-tools-tab.d.vue.ts +0 -20
  46. package/dist/runtime/embed/components/configuration/chat-configuration-tela-tools-tab.vue +0 -146
  47. package/dist/runtime/embed/components/configuration/chat-configuration-tela-tools-tab.vue.d.ts +0 -20
  48. package/dist/runtime/workspace/composables/workspace-context-files.d.ts +0 -19
  49. package/dist/runtime/workspace/composables/workspace-context-files.js +0 -83
  50. package/dist/runtime/workspace/composables/workspace-external-skills.d.ts +0 -22
  51. package/dist/runtime/workspace/composables/workspace-external-skills.js +0 -137
  52. package/dist/runtime/workspace/composables/workspace-personalization.d.ts +0 -6
  53. package/dist/runtime/workspace/composables/workspace-personalization.js +0 -18
  54. package/dist/runtime/workspace/composables/workspace-tela-tools.d.ts +0 -13
  55. package/dist/runtime/workspace/composables/workspace-tela-tools.js +0 -91
@@ -27,11 +27,15 @@ const props = defineProps({
27
27
  conversationId: { type: [String, null], required: false },
28
28
  initialConversationId: { type: [String, null], required: false, default: null },
29
29
  hideSidebar: { type: Boolean, required: false, default: true },
30
+ sidebar: { type: Object, required: false },
30
31
  hideSettings: { type: Boolean, required: false, default: false },
31
32
  user: { type: [Object, null], required: false },
32
33
  features: { type: Object, required: false }
33
34
  });
34
35
  const emit = defineEmits(["update:conversationId"]);
36
+ const sidebarPosition = computed(() => props.sidebar?.position ?? "left");
37
+ const sidebarWidth = computed(() => props.sidebar?.width ?? 240);
38
+ const sidebarBottomHeight = computed(() => Math.min(100, Math.max(0, props.sidebar?.bottomHeight ?? 50)));
35
39
  const chatApi = useChatApi();
36
40
  const embedConfig = useEmbedConfig();
37
41
  const chatAction = useChatAction();
@@ -425,8 +429,10 @@ async function handleDelete() {
425
429
  <!-- Sidebar -->
426
430
  <div
427
431
  v-if="!hideSidebar && !isMobile"
428
- w-240px h-full flex="~ col" flex-shrink-0
429
- bg-neutral-50 b-r=".5px neutral-200"
432
+ h-full flex="~ col" flex-shrink-0
433
+ bg-neutral-50
434
+ :style="{ width: `${sidebarWidth}px` }"
435
+ :class="sidebarPosition === 'right' ? 'order-last border-l-0.5px border-l-neutral-200' : 'border-r-0.5px border-r-neutral-200'"
430
436
  >
431
437
  <div px-12px pt-16px pb-8px flex gap-8px>
432
438
  <button
@@ -444,7 +450,11 @@ async function handleDelete() {
444
450
  <ChatConversationNewGroupButton />
445
451
  </div>
446
452
 
447
- <div flex-1 overflow-y-auto px-4px>
453
+ <div
454
+ min-h-0 overflow-y-auto px-4px
455
+ :class="$slots['sidebar-bottom'] ? '' : 'flex-1'"
456
+ :style="$slots['sidebar-bottom'] ? { flexGrow: 100 - sidebarBottomHeight, flexBasis: 0 } : void 0"
457
+ >
448
458
  <ChatConversationList
449
459
  :conversations="visibleConversations"
450
460
  :current-id="activeConversationId ?? void 0"
@@ -455,6 +465,15 @@ async function handleDelete() {
455
465
  :loading="conversationsLoading"
456
466
  />
457
467
  </div>
468
+
469
+ <div
470
+ v-if="$slots['sidebar-bottom']"
471
+ min-h-0 overflow-y-auto
472
+ b-t=".5px neutral-200"
473
+ :style="{ flexGrow: sidebarBottomHeight, flexBasis: 0 }"
474
+ >
475
+ <slot name="sidebar-bottom" />
476
+ </div>
458
477
  </div>
459
478
 
460
479
  <!-- Main content -->
@@ -1,15 +1,20 @@
1
1
  import type { ChatFeatureConfig } from '../feature-config.js';
2
- import type { ChatActor } from '../types.js';
2
+ import type { ChatActor, ChatSidebarConfig } from '../types.js';
3
3
  type EmbedUser = ChatActor;
4
4
  type __VLS_Props = {
5
5
  conversationId?: string | null;
6
6
  initialConversationId?: string | null;
7
7
  hideSidebar?: boolean;
8
+ sidebar?: ChatSidebarConfig;
8
9
  hideSettings?: boolean;
9
10
  user?: EmbedUser | null;
10
11
  features?: Partial<ChatFeatureConfig>;
11
12
  };
12
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
13
+ declare var __VLS_11: {};
14
+ type __VLS_Slots = {} & {
15
+ 'sidebar-bottom'?: (props: typeof __VLS_11) => any;
16
+ };
17
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
13
18
  "update:conversationId": (value: string | null) => any;
14
19
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
15
20
  "onUpdate:conversationId"?: ((value: string | null) => any) | undefined;
@@ -18,5 +23,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
18
23
  hideSidebar: boolean;
19
24
  initialConversationId: string | null;
20
25
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
26
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
21
27
  declare const _default: typeof __VLS_export;
22
28
  export default _default;
29
+ type __VLS_WithSlots<T, S> = T & {
30
+ new (): {
31
+ $slots: S;
32
+ };
33
+ };
@@ -1,6 +1,10 @@
1
1
  import { type ChatActionPayload } from '../../messages/composables/chat-action.js';
2
2
  import { type MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
3
- declare const __VLS_export: import("vue").DefineComponent<import("../types.js").DefaultChatEmbedProps | import("../types.js").TelaAgentChatEmbedProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
3
+ declare var __VLS_11: {};
4
+ type __VLS_Slots = {} & {
5
+ 'sidebar-bottom'?: (props: typeof __VLS_11) => any;
6
+ };
7
+ declare const __VLS_base: import("vue").DefineComponent<import("../types.js").DefaultChatEmbedProps | import("../types.js").TelaAgentChatEmbedProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
8
  "update:conversationId": (value: string | null) => any;
5
9
  messageFeedback: (payload: MessageFeedbackPayload) => any;
6
10
  action: (payload: ChatActionPayload) => any;
@@ -9,5 +13,11 @@ declare const __VLS_export: import("vue").DefineComponent<import("../types.js").
9
13
  onMessageFeedback?: ((payload: MessageFeedbackPayload) => any) | undefined;
10
14
  onAction?: ((payload: ChatActionPayload) => any) | undefined;
11
15
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
17
  declare const _default: typeof __VLS_export;
13
18
  export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -12,6 +12,7 @@ const props = defineProps({
12
12
  conversationScope: { type: [String, null], required: false },
13
13
  defaultConversationCreatorFilter: { type: null, required: false },
14
14
  hideSidebar: { type: Boolean, required: false },
15
+ sidebar: { type: Object, required: false },
15
16
  hideSettings: { type: Boolean, required: false },
16
17
  loadingMessages: { type: [Array, null], required: false },
17
18
  loadingMessagesMode: { type: [String, null], required: false },
@@ -88,9 +89,14 @@ provideMessageFeedback((payload) => {
88
89
  :conversation-id="conversationId"
89
90
  :initial-conversation-id="initialConversationId"
90
91
  :hide-sidebar="hideSidebar"
92
+ :sidebar="sidebar"
91
93
  :hide-settings="hideSettings"
92
94
  :user="normalizedTelaAgentId ? null : user"
93
95
  :features="features"
94
96
  @update:conversation-id="$emit('update:conversationId', $event)"
95
- />
97
+ >
98
+ <template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
99
+ <slot name="sidebar-bottom" />
100
+ </template>
101
+ </ChatEmbedInner>
96
102
  </template>
@@ -1,6 +1,10 @@
1
1
  import { type ChatActionPayload } from '../../messages/composables/chat-action.js';
2
2
  import { type MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
3
- declare const __VLS_export: import("vue").DefineComponent<import("../types.js").DefaultChatEmbedProps | import("../types.js").TelaAgentChatEmbedProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
3
+ declare var __VLS_11: {};
4
+ type __VLS_Slots = {} & {
5
+ 'sidebar-bottom'?: (props: typeof __VLS_11) => any;
6
+ };
7
+ declare const __VLS_base: import("vue").DefineComponent<import("../types.js").DefaultChatEmbedProps | import("../types.js").TelaAgentChatEmbedProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
4
8
  "update:conversationId": (value: string | null) => any;
5
9
  messageFeedback: (payload: MessageFeedbackPayload) => any;
6
10
  action: (payload: ChatActionPayload) => any;
@@ -9,5 +13,11 @@ declare const __VLS_export: import("vue").DefineComponent<import("../types.js").
9
13
  onMessageFeedback?: ((payload: MessageFeedbackPayload) => any) | undefined;
10
14
  onAction?: ((payload: ChatActionPayload) => any) | undefined;
11
15
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
12
17
  declare const _default: typeof __VLS_export;
13
18
  export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,13 @@
1
+ import type { WorkspaceAgentStatusResponse } from '../../../types/schemas/chat/workspace-agent.js';
2
+ type __VLS_Props = {
3
+ status: WorkspaceAgentStatusResponse | null;
4
+ loading: boolean;
5
+ creating: boolean;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
+ create: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onCreate?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -0,0 +1,167 @@
1
+ <script setup>
2
+ const props = defineProps({
3
+ status: { type: null, required: true },
4
+ loading: { type: Boolean, required: true },
5
+ creating: { type: Boolean, required: true }
6
+ });
7
+ const emit = defineEmits(["create"]);
8
+ const customizationLabels = {
9
+ system_message: "Prompt personalizado",
10
+ context_files: "Arquivos de contexto",
11
+ canvas_tools: "Skills Tela",
12
+ external_skills: "Skills externas"
13
+ };
14
+ function openInTela() {
15
+ if (props.status?.telaAgentUrl)
16
+ window.open(props.status.telaAgentUrl, "_blank", "noopener");
17
+ }
18
+ </script>
19
+
20
+ <template>
21
+ <div mb-24px>
22
+ <h2 text-16px font-semibold text-primary tracking="-.2px" leading-20px>
23
+ Agente
24
+ </h2>
25
+ <div h-px bg-gray-200 mt-24px />
26
+ </div>
27
+
28
+ <div v-if="loading || !status" flex="~ col" gap-8px>
29
+ <TelaSkeleton h-88px />
30
+ <TelaSkeleton h-48px />
31
+ </div>
32
+
33
+ <div
34
+ v-else-if="status.mode === 'default'"
35
+ b=".5px gray-200" rounded-12px p-20px
36
+ flex="~ col" gap-16px
37
+ >
38
+ <div flex items-center gap-12px>
39
+ <div w-40px h-40px rounded-full bg-muted flex items-center justify-center shrink-0>
40
+ <div i-ph-chat-circle-text text-20px text-icon />
41
+ </div>
42
+ <div flex="~ col" gap-2px flex-1 min-w-0>
43
+ <span text-14px font-semibold text-primary tracking="-.15px" leading-18px>
44
+ Chat genérico do Tela
45
+ </span>
46
+ <span text-13px text-secondary leading-16px>
47
+ Agente padrão, mantido pela equipe Tela
48
+ </span>
49
+ </div>
50
+ <TelaBadge icon="i-ph-check">
51
+ Padrão
52
+ </TelaBadge>
53
+ </div>
54
+
55
+ <p text-14px text-secondary tracking="-.15px" leading-20px>
56
+ Este workspace usa o agente padrão do chat. Prompt, arquivos de contexto
57
+ e skills são os da configuração genérica.
58
+ </p>
59
+
60
+ <div bg-muted rounded-8px p-12px flex items-start gap-8px>
61
+ <div i-ph-info text-16px text-icon mt-1px shrink-0 />
62
+ <p text-13px text-secondary leading-18px>
63
+ Para personalizar o comportamento do chat, a configuração é feita na
64
+ plataforma Tela, com um agente dedicado ao seu workspace.
65
+ </p>
66
+ </div>
67
+ </div>
68
+
69
+ <div
70
+ v-else-if="status.mode === 'custom'"
71
+ b=".5px gray-200" rounded-12px p-20px
72
+ flex="~ col" gap-16px
73
+ >
74
+ <div flex items-center gap-12px>
75
+ <div w-40px h-40px rounded-full bg-muted flex items-center justify-center shrink-0>
76
+ <div i-ph-robot text-20px text-icon />
77
+ </div>
78
+ <div flex="~ col" gap-2px flex-1 min-w-0>
79
+ <span text-14px font-semibold text-primary tracking="-.15px" leading-18px>
80
+ Agente dedicado
81
+ </span>
82
+ <span text-13px text-secondary leading-16px>
83
+ Este workspace executa um agente próprio no Tela
84
+ </span>
85
+ </div>
86
+ <TelaBadge variant="filled" icon="i-ph-check" container-class="bg-green-100" text-class="text-green-700">
87
+ Ativo
88
+ </TelaBadge>
89
+ </div>
90
+
91
+ <div bg-muted rounded-8px p-12px flex items-start gap-8px>
92
+ <div i-ph-info text-16px text-icon mt-1px shrink-0 />
93
+ <p text-13px text-secondary leading-18px>
94
+ As configurações deste workspace foram migradas para um agente dedicado
95
+ no Tela. Prompt, arquivos de contexto e skills agora são gerenciados por
96
+ lá — alterações feitas no Tela valem para as próximas conversas.
97
+ </p>
98
+ </div>
99
+
100
+ <div flex="~ col" gap-6px>
101
+ <span text-12px text-secondary leading-16px>
102
+ ID do agente
103
+ </span>
104
+ <div
105
+ b=".5px gray-200" rounded-8px pl-12px pr-6px py-6px
106
+ flex items-center gap-8px
107
+ >
108
+ <span font-mono text-13px text-primary leading-18px truncate flex-1>
109
+ {{ status.telaAgentId }}
110
+ </span>
111
+ <TelaCopyButton :content="status.telaAgentId ?? ''" variant="ghost" size="sm" />
112
+ </div>
113
+ </div>
114
+
115
+ <div flex justify-end>
116
+ <TelaButton icon="i-ph-arrow-square-out" @click="openInTela">
117
+ Abrir no Tela
118
+ </TelaButton>
119
+ </div>
120
+ </div>
121
+
122
+ <div
123
+ v-else
124
+ b=".5px gray-200" rounded-12px p-20px
125
+ flex="~ col" gap-16px
126
+ >
127
+ <div bg-warning rounded-8px p-12px flex items-start gap-8px>
128
+ <div i-ph-warning text-16px text-warning mt-1px shrink-0 />
129
+ <div flex="~ col" gap-4px>
130
+ <span text-13px font-semibold text-primary leading-18px>
131
+ Configuração pendente
132
+ </span>
133
+ <p text-13px text-secondary leading-18px>
134
+ Este workspace tem personalizações do chat antigo que ainda não foram
135
+ migradas para um agente Tela. Até concluir esta configuração, novas
136
+ mensagens não podem ser enviadas.
137
+ </p>
138
+ </div>
139
+ </div>
140
+
141
+ <div v-if="status.pendingCustomizations.length > 0" flex="~ col" gap-6px>
142
+ <span text-12px text-secondary leading-16px>
143
+ Personalizações detectadas
144
+ </span>
145
+ <div flex flex-wrap gap-6px>
146
+ <TelaBadge
147
+ v-for="customization in status.pendingCustomizations"
148
+ :key="customization"
149
+ >
150
+ {{ customizationLabels[customization] }}
151
+ </TelaBadge>
152
+ </div>
153
+ </div>
154
+
155
+ <p text-14px text-secondary tracking="-.15px" leading-20px>
156
+ Crie um agente dedicado a partir do modelo padrão do chat. As personalizações
157
+ listadas não são migradas automaticamente — configure-as no Tela depois de
158
+ criar o agente.
159
+ </p>
160
+
161
+ <div flex justify-end>
162
+ <TelaButton icon="i-ph-plus" leading :loading="creating" @click="emit('create')">
163
+ Criar agente no Tela
164
+ </TelaButton>
165
+ </div>
166
+ </div>
167
+ </template>
@@ -0,0 +1,13 @@
1
+ import type { WorkspaceAgentStatusResponse } from '../../../types/schemas/chat/workspace-agent.js';
2
+ type __VLS_Props = {
3
+ status: WorkspaceAgentStatusResponse | null;
4
+ loading: boolean;
5
+ creating: boolean;
6
+ };
7
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
8
+ create: () => any;
9
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
10
+ onCreate?: (() => any) | undefined;
11
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
+ declare const _default: typeof __VLS_export;
13
+ export default _default;
@@ -1,7 +1,7 @@
1
- import type { DefineSetupFnComponent } from 'vue';
1
+ import type { DefineSetupFnComponent, SlotsType } from 'vue';
2
2
  import type { ChatActionPayload } from '../../messages/composables/chat-action.js';
3
3
  import type { ChatFeatureConfig } from '../feature-config.js';
4
- import type { DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
4
+ import type { ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
5
5
 
6
6
  type MeistrariChatEmbedEmits = {
7
7
  /** Fired when the active conversation changes. Pairs with `v-model:conversation-id`. */
@@ -10,6 +10,11 @@ type MeistrariChatEmbedEmits = {
10
10
  'action': (payload: ChatActionPayload) => any;
11
11
  };
12
12
 
13
+ type MeistrariChatEmbedSlots = SlotsType<{
14
+ /** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. */
15
+ 'sidebar-bottom'?: () => any;
16
+ }>;
17
+
13
18
  /**
14
19
  * Embedded Meistrari chat surface. Auto-registered by the `@meistrari/chat-nuxt`
15
20
  * module — no manual import needed in templates.
@@ -36,7 +41,7 @@ type MeistrariChatEmbedEmits = {
36
41
  * </template>
37
42
  * ```
38
43
  */
39
- declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits>;
44
+ declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
40
45
 
41
46
  export default MeistrariChatEmbed;
42
- export type { ChatActionPayload, ChatFeatureConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps };
47
+ export type { ChatActionPayload, ChatFeatureConfig, ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps };
@@ -6,6 +6,7 @@ const props = defineProps({
6
6
  conversationScope: { type: [String, null], required: false },
7
7
  defaultConversationCreatorFilter: { type: null, required: false },
8
8
  hideSidebar: { type: Boolean, required: false },
9
+ sidebar: { type: Object, required: false },
9
10
  hideSettings: { type: Boolean, required: false },
10
11
  loadingMessages: { type: [Array, null], required: false },
11
12
  loadingMessagesMode: { type: [String, null], required: false },
@@ -20,6 +21,7 @@ const props = defineProps({
20
21
  features: { type: Object, required: false }
21
22
  });
22
23
  defineEmits(["update:conversationId", "action", "messageFeedback"]);
24
+ defineSlots();
23
25
  const hideSettings = computed(() => props.hideSettings ?? false);
24
26
  </script>
25
27
 
@@ -33,6 +35,7 @@ const hideSettings = computed(() => props.hideSettings ?? false);
33
35
  :conversation-scope="conversationScope"
34
36
  :default-conversation-creator-filter="defaultConversationCreatorFilter"
35
37
  :hide-sidebar="hideSidebar"
38
+ :sidebar="sidebar"
36
39
  :hide-settings="hideSettings"
37
40
  :features="features"
38
41
  :loading-messages="loadingMessages"
@@ -44,7 +47,11 @@ const hideSettings = computed(() => props.hideSettings ?? false);
44
47
  @update:conversation-id="$emit('update:conversationId', $event)"
45
48
  @action="$emit('action', $event)"
46
49
  @message-feedback="$emit('messageFeedback', $event)"
47
- />
50
+ >
51
+ <template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
52
+ <slot name="sidebar-bottom" />
53
+ </template>
54
+ </ChatEmbed>
48
55
  <ChatEmbed
49
56
  v-else
50
57
  :workspace-settings="workspaceSettings"
@@ -54,6 +61,7 @@ const hideSettings = computed(() => props.hideSettings ?? false);
54
61
  :conversation-scope="conversationScope"
55
62
  :default-conversation-creator-filter="defaultConversationCreatorFilter"
56
63
  :hide-sidebar="hideSidebar"
64
+ :sidebar="sidebar"
57
65
  :hide-settings="hideSettings"
58
66
  :features="features"
59
67
  :loading-messages="loadingMessages"
@@ -65,5 +73,9 @@ const hideSettings = computed(() => props.hideSettings ?? false);
65
73
  @update:conversation-id="$emit('update:conversationId', $event)"
66
74
  @action="$emit('action', $event)"
67
75
  @message-feedback="$emit('messageFeedback', $event)"
68
- />
76
+ >
77
+ <template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
78
+ <slot name="sidebar-bottom" />
79
+ </template>
80
+ </ChatEmbed>
69
81
  </template>
@@ -1,7 +1,7 @@
1
- import type { DefineSetupFnComponent } from 'vue';
1
+ import type { DefineSetupFnComponent, SlotsType } from 'vue';
2
2
  import type { ChatActionPayload } from '../../messages/composables/chat-action.js';
3
3
  import type { ChatFeatureConfig } from '../feature-config.js';
4
- import type { DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
4
+ import type { ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
5
5
 
6
6
  type MeistrariChatEmbedEmits = {
7
7
  /** Fired when the active conversation changes. Pairs with `v-model:conversation-id`. */
@@ -10,6 +10,11 @@ type MeistrariChatEmbedEmits = {
10
10
  'action': (payload: ChatActionPayload) => any;
11
11
  };
12
12
 
13
+ type MeistrariChatEmbedSlots = SlotsType<{
14
+ /** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. */
15
+ 'sidebar-bottom'?: () => any;
16
+ }>;
17
+
13
18
  /**
14
19
  * Embedded Meistrari chat surface. Auto-registered by the `@meistrari/chat-nuxt`
15
20
  * module — no manual import needed in templates.
@@ -36,7 +41,7 @@ type MeistrariChatEmbedEmits = {
36
41
  * </template>
37
42
  * ```
38
43
  */
39
- declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits>;
44
+ declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
40
45
 
41
46
  export default MeistrariChatEmbed;
42
- export type { ChatActionPayload, ChatFeatureConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps };
47
+ export type { ChatActionPayload, ChatFeatureConfig, ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps };
@@ -10,6 +10,18 @@ export type ChatActor = {
10
10
  email?: string | null;
11
11
  image?: string | null;
12
12
  };
13
+ export type ChatSidebarConfig = {
14
+ /** Which edge of the chat surface renders the conversation sidebar. Defaults to left. */
15
+ position?: 'left' | 'right';
16
+ /** Sidebar width in pixels. Defaults to 240. */
17
+ width?: number;
18
+ /**
19
+ * Height of the `sidebar-bottom` slot pane as a percentage (0–100) of the
20
+ * sidebar's conversation area. Only applies when the slot is provided.
21
+ * Defaults to 50.
22
+ */
23
+ bottomHeight?: number;
24
+ };
13
25
  export type ChatEmbedSharedProps = {
14
26
  /** Controlled conversation id. Use with `v-model:conversation-id` when the host owns active conversation state. */
15
27
  conversationId?: string | null;
@@ -21,6 +33,8 @@ export type ChatEmbedSharedProps = {
21
33
  defaultConversationCreatorFilter?: ConversationCreatorFilter;
22
34
  /** Hide the conversation list and render only the active chat surface. */
23
35
  hideSidebar?: boolean;
36
+ /** Layout options for the conversation sidebar (edge and `sidebar-bottom` split). */
37
+ sidebar?: ChatSidebarConfig;
24
38
  /** Hide workspace settings actions while keeping the chat header and content unchanged. */
25
39
  hideSettings?: boolean;
26
40
  /** Custom pending-response messages shown while the assistant is working. */
@@ -0,0 +1,2 @@
1
+ export declare const MAX_FILES = 10;
2
+ export declare const MAX_FILE_SIZE: number;
@@ -0,0 +1,2 @@
1
+ export const MAX_FILES = 10;
2
+ export const MAX_FILE_SIZE = 10 * 1024 * 1024;
@@ -1,8 +1,8 @@
1
1
  <script setup>
2
2
  import { useFileUpload } from "../../files/composables/file-upload";
3
- import { useTela } from "../../shared/composables/tela";
4
- import { MAX_FILES, MAX_FILE_SIZE } from "../../workspace/composables/workspace-context-files";
3
+ import { MAX_FILES, MAX_FILE_SIZE } from "../../files/file-limits";
5
4
  import { formatFileSize } from "../../files/formatting";
5
+ import { useTela } from "../../shared/composables/tela";
6
6
  const props = defineProps({
7
7
  systemMessage: { type: [String, null], required: true },
8
8
  contextFiles: { type: [Array, null], required: true },
@@ -1,8 +1,8 @@
1
1
  <script setup>
2
2
  import { useFileUpload } from "../../files/composables/file-upload";
3
+ import { MAX_FILE_SIZE, MAX_FILES } from "../../files/file-limits";
3
4
  import { useInputHistory } from "../composables/input-history";
4
5
  import { useMentionAutocomplete } from "../composables/mention-autocomplete";
5
- import { MAX_FILE_SIZE, MAX_FILES } from "../../workspace/composables/workspace-context-files";
6
6
  import { getAgentInputReadiness } from "../input-readiness";
7
7
  import { formatFileSize } from "../../files/formatting";
8
8
  import { getMimeIcon, getMimeLabel } from "../../files/icons";
@@ -15,11 +15,12 @@ import {
15
15
  } from "../message-state.js";
16
16
  import { exportConversationToMarkdown } from "../../conversations/export.js";
17
17
  import { resolveChatStateScope } from "../../conversations/scope.js";
18
- import { getChatApiErrorMessage } from "../../shared/chat-api-error.js";
18
+ import { getChatApiErrorCode, getChatApiErrorMessage } from "../../shared/chat-api-error.js";
19
19
  import { useChatApi } from "../../shared/composables/chat-api.js";
20
20
  import { useConversationFileActions } from "../../files/composables/conversation-files.js";
21
21
  import { useEmbedConfig } from "../../embed/composables/embed-config.js";
22
22
  import { usePolling } from "../../shared/composables/polling.js";
23
+ const WORKSPACE_AGENT_NOT_READY_TEXT = "O agente deste workspace ainda n\xE3o foi configurado no Tela. Abra as configura\xE7\xF5es do workspace para criar o agente.";
23
24
  function resolveTelaAgentInputs(messageInputs, configuredInputs) {
24
25
  const inputs = messageInputs ?? configuredInputs ?? void 0;
25
26
  return inputs?.length ? inputs.map((input) => ({ ...input })) : void 0;
@@ -221,7 +222,7 @@ export function useChat() {
221
222
  (msg) => msg.id !== optimisticUserMessage.id && msg.id !== optimisticAssistantMessage.id
222
223
  );
223
224
  stopPolling();
224
- const message = err instanceof Error ? err.message : "Erro ao enviar mensagem";
225
+ const message = getChatApiErrorCode(err) === "workspace_agent_not_ready" ? WORKSPACE_AGENT_NOT_READY_TEXT : err instanceof Error ? err.message : "Erro ao enviar mensagem";
225
226
  error.value = message;
226
227
  Sentry.captureException(err);
227
228
  return null;
@@ -303,7 +304,7 @@ export function useChat() {
303
304
  return true;
304
305
  } catch (err) {
305
306
  messages.value = restoreAssistantMessageAfterRetryFailure(messages.value, retry.originalMessage);
306
- const errorMessage = err instanceof Error ? err.message : "Erro ao reenviar mensagem";
307
+ const errorMessage = getChatApiErrorCode(err) === "workspace_agent_not_ready" ? WORKSPACE_AGENT_NOT_READY_TEXT : err instanceof Error ? err.message : "Erro ao reenviar mensagem";
307
308
  error.value = errorMessage;
308
309
  Sentry.captureException(err);
309
310
  return false;
@@ -1 +1,2 @@
1
1
  export declare function getChatApiErrorMessage(error: unknown): string | null;
2
+ export declare function getChatApiErrorCode(error: unknown): string | null;
@@ -10,3 +10,8 @@ export function getChatApiErrorMessage(error) {
10
10
  const data = root && isRecord(root.data) ? root.data : null;
11
11
  return stringField(data, "statusMessage") ?? stringField(data, "error") ?? stringField(data, "message") ?? stringField(root, "statusMessage") ?? stringField(root, "message");
12
12
  }
13
+ export function getChatApiErrorCode(error) {
14
+ const root = isRecord(error) ? error : null;
15
+ const data = root && isRecord(root.data) ? root.data : null;
16
+ return stringField(data, "code");
17
+ }
@@ -1,5 +1,5 @@
1
1
  export type { ChatFeatureConfig } from '../embed/feature-config.js';
2
- export type { ChatActor, ChatEmbedSharedProps, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps, } from '../embed/types.js';
2
+ export type { ChatActor, ChatEmbedSharedProps, ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps, } from '../embed/types.js';
3
3
  export type { ChatActionPayload } from '../messages/composables/chat-action.js';
4
4
  export type { MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, } from '../messages/composables/chat-feedback.js';
5
5
  export type { TelaAgentExecutionInput } from './schemas/integrations/tela-agent-api.js';
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod';
2
+ export declare const workspaceAgentModes: readonly ["default", "custom", "setup_required"];
3
+ export declare const workspaceAgentModeSchema: z.ZodEnum<{
4
+ default: "default";
5
+ custom: "custom";
6
+ setup_required: "setup_required";
7
+ }>;
8
+ export type WorkspaceAgentMode = z.infer<typeof workspaceAgentModeSchema>;
9
+ export declare const workspaceAgentCustomizations: readonly ["system_message", "context_files", "canvas_tools", "external_skills"];
10
+ export declare const workspaceAgentCustomizationSchema: z.ZodEnum<{
11
+ system_message: "system_message";
12
+ context_files: "context_files";
13
+ canvas_tools: "canvas_tools";
14
+ external_skills: "external_skills";
15
+ }>;
16
+ export type WorkspaceAgentCustomization = z.infer<typeof workspaceAgentCustomizationSchema>;
17
+ export declare const workspaceAgentStatusResponseSchema: z.ZodObject<{
18
+ workspaceId: z.ZodString;
19
+ mode: z.ZodEnum<{
20
+ default: "default";
21
+ custom: "custom";
22
+ setup_required: "setup_required";
23
+ }>;
24
+ telaAgentId: z.ZodNullable<z.ZodString>;
25
+ telaAgentUrl: z.ZodNullable<z.ZodString>;
26
+ pendingCustomizations: z.ZodArray<z.ZodEnum<{
27
+ system_message: "system_message";
28
+ context_files: "context_files";
29
+ canvas_tools: "canvas_tools";
30
+ external_skills: "external_skills";
31
+ }>>;
32
+ }, z.core.$strip>;
33
+ export type WorkspaceAgentStatusResponse = z.infer<typeof workspaceAgentStatusResponseSchema>;
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ export const workspaceAgentModes = ['default', 'custom', 'setup_required'];
3
+ export const workspaceAgentModeSchema = z.enum(workspaceAgentModes);
4
+ export const workspaceAgentCustomizations = ['system_message', 'context_files', 'canvas_tools', 'external_skills'];
5
+ export const workspaceAgentCustomizationSchema = z.enum(workspaceAgentCustomizations);
6
+ export const workspaceAgentStatusResponseSchema = z.object({
7
+ workspaceId: z.string().min(1),
8
+ mode: workspaceAgentModeSchema,
9
+ telaAgentId: z.string().nullable(),
10
+ telaAgentUrl: z.string().nullable(),
11
+ pendingCustomizations: z.array(workspaceAgentCustomizationSchema),
12
+ });