@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
package/README.md CHANGED
@@ -82,7 +82,7 @@ Set `chatNuxt.validateConfig` to `'warn'` to log a warning when `chatApiUrl` is
82
82
 
83
83
  UI features are configured per component instance, not at the module level: the embed takes a `:features` prop (`ChatFeatureConfig`) and `<ChatConfigurationModal>` takes `show-credentials-tab`.
84
84
 
85
- ### Auth modes
85
+ ### 3. Auth modes
86
86
 
87
87
  `@meistrari/chat-nuxt` can run with either auth mode exposed by `@meistrari/auth-nuxt`:
88
88
 
@@ -120,7 +120,7 @@ The chat workspace is resolved from the authenticated `activeOrganization` provi
120
120
 
121
121
  `<MeistrariChatEmbed />` has two mutually exclusive runtimes:
122
122
 
123
- - **Default chat mode** uses the Chat API and the workspace's configured Tela agent. Runtime configuration, entitlements, and workspace-specific agent selection are owned by `@meistrari/chat-api`.
123
+ - **Default chat mode** uses the Chat API and the workspace's configured Tela agent. Runtime configuration, entitlements, and workspace-specific agent selection are owned by `@meistrari/chat-api`. Workspaces whose legacy customization has not been migrated to a Tela agent are not ready to chat: sends fail with `workspace_agent_not_ready` and the embed surfaces guidance pointing to the settings modal, where the **Agente** tab offers a one-click agent creation.
124
124
  - **Tela agent mode** uses a configured Tela agent directly. Pass `telaAgentId`; the embed sends user messages to `POST /agent/:id/run`, polls `GET /agent/sessions/:sessionId`, and ends sessions with `DELETE /agent/sessions/:sessionId`.
125
125
 
126
126
  ```vue
@@ -183,12 +183,21 @@ Key props for embedding:
183
183
  All prop, feature-flag, and event payload types are importable from the package root (or the `types/embed` subpath):
184
184
 
185
185
  ```ts
186
- import type { ChatActionPayload, ChatFeatureConfig, MeistrariChatEmbedProps } from '@meistrari/chat-nuxt'
186
+ import type {
187
+ ChatActionPayload,
188
+ ChatFeatureConfig,
189
+ MeistrariChatEmbedProps,
190
+ MessageFeedbackConfig,
191
+ MessageFeedbackPayload,
192
+ MessageFeedbackRating,
193
+ } from '@meistrari/chat-nuxt'
187
194
  ```
188
195
 
189
196
  | Prop | Type | Default | Description |
190
197
  |------|------|---------|-------------|
191
198
  | `hideSidebar` | `boolean` | `false` | Hide conversation list sidebar |
199
+ | `sidebar` | `ChatSidebarConfig` | `undefined` | Sidebar layout: `{ position?: 'left' \| 'right', width?: number, bottomHeight?: number }`. `position` picks the edge (default `'left'`); `width` is the sidebar width in pixels (default `240`); `bottomHeight` is the `sidebar-bottom` pane height as a percentage 0–100 of the conversation area (default `50`) |
200
+ | `hideSettings` | `boolean` | `false` | Hide workspace settings actions while keeping the chat header and content unchanged |
192
201
  | `conversationId` | `string \| null` | `null` | Controlled conversation (supports v-model) |
193
202
  | `initialConversationId` | `string \| null` | `null` | Open this conversation on mount |
194
203
  | `conversationScope` | `string \| null` | `null` | Isolate conversation history by technical scope within the current workspace and runtime |
@@ -198,8 +207,12 @@ import type { ChatActionPayload, ChatFeatureConfig, MeistrariChatEmbedProps } fr
198
207
  | `workspaceSettings` | `WorkspaceSettings \| null` | `null` | Override settings from host app |
199
208
  | `user` | `ChatActor \| null` | `null` | Override current user display info |
200
209
  | `features` | `Partial<ChatFeatureConfig>` | `{}` | Toggle optional features |
201
- | `loadingMessages` | `string[] \| null` | Default chat messages | Override pending-response messages |
210
+ | `loadingMessages` | `readonly string[] \| null` | Default chat messages | Override pending-response messages |
202
211
  | `loadingMessagesMode` | `'ordered' \| 'random' \| null` | `'ordered'` | Show custom messages sequentially or randomly |
212
+ | `customComponents` | `Record<string, Component>` | `undefined` | Custom markdown renderers keyed by markdown node or tag name |
213
+ | `customHtmlTags` | `readonly string[]` | `undefined` | Extra HTML tags allowed by the markdown renderer |
214
+ | `feedbackConfig` | `MessageFeedbackConfig \| null` | `undefined` | Enables 👍/👎 feedback on assistant messages; providing the prop (even `{}`) shows the controls |
215
+ | `messageFeedback` | `Record<string, MessageFeedbackRating> \| null` | `undefined` | Host-persisted votes keyed by message id; when provided, it is the single source of truth for the selected thumbs |
203
216
 
204
217
  `loadingMessagesMode` only applies when `loadingMessages` has at least one non-empty message.
205
218
 
@@ -224,6 +237,22 @@ Scoped embeds only see conversations created with the same scope. Unscoped embed
224
237
  | Event | Payload | Description |
225
238
  |-------|---------|-------------|
226
239
  | `update:conversationId` | `string \| null` | Active conversation changed |
240
+ | `action` | `ChatActionPayload` | Custom action triggered from chat content (`{ name, data, messageId? }`) |
241
+ | `messageFeedback` | `MessageFeedbackPayload` | User voted on an assistant message (see [Message Feedback](#optional-message-feedback)) |
242
+
243
+ **Slots:**
244
+
245
+ | Slot | Description |
246
+ |------|-------------|
247
+ | `sidebar-bottom` | Splits the desktop sidebar into two panes and renders your content in the bottom one, below the conversation list. Each pane scrolls independently. Size it with `sidebar.bottomHeight` (percentage, default `50`). Not rendered on mobile or when `hideSidebar` is set. |
248
+
249
+ ```vue
250
+ <MeistrariChatEmbed :sidebar="{ position: 'right', width: 300, bottomHeight: 30 }">
251
+ <template #sidebar-bottom>
252
+ <MyPinnedDocuments />
253
+ </template>
254
+ </MeistrariChatEmbed>
255
+ ```
227
256
 
228
257
  ## Optional: Feature Flags
229
258
 
@@ -300,11 +329,55 @@ const features = computed(() => ({
300
329
  </template>
301
330
  ```
302
331
 
332
+ ## Optional: Message Feedback
333
+
334
+ Assistant messages can carry 👍/👎 controls. The package renders the controls and collects the vote; **persistence is owned by the host** — nothing is stored by `chat-nuxt`.
335
+
336
+ Passing `feedbackConfig` (even `{}`) enables the controls:
337
+
338
+ ```vue
339
+ <script setup lang="ts">
340
+ import type { MessageFeedbackPayload, MessageFeedbackRating } from '@meistrari/chat-nuxt'
341
+
342
+ const votes = ref<Record<string, MessageFeedbackRating>>({})
343
+
344
+ async function onFeedback(payload: MessageFeedbackPayload) {
345
+ // payload: { conversationId, messageId, rating, reasons, comment }
346
+ await saveVoteToMyBackend(payload)
347
+ votes.value = { ...votes.value, [payload.messageId]: payload.rating }
348
+ }
349
+ </script>
350
+
351
+ <template>
352
+ <MeistrariChatEmbed
353
+ :feedback-config="{
354
+ negativeReasons: ['Resposta incorreta', 'Fora do tema', 'Incompleta'],
355
+ requireReason: true,
356
+ }"
357
+ :message-feedback="votes"
358
+ @message-feedback="onFeedback"
359
+ />
360
+ </template>
361
+ ```
362
+
363
+ `MessageFeedbackConfig` fields:
364
+
365
+ | Field | Effect |
366
+ |-------|--------|
367
+ | `positiveReasons` | Reason chips offered on a positive vote. Empty or omitted: 👍 submits directly |
368
+ | `negativeReasons` | Reason chips offered on a negative vote |
369
+ | `requireReason` | Blocks a bare negative vote: requires at least one reason chip when `negativeReasons` are configured, otherwise a non-empty comment |
370
+
371
+ `messageFeedback` controls which thumb renders selected:
372
+
373
+ - **Provided** (controlled): only host-persisted votes render. Update the map as `message-feedback` events are saved — optimistically or after persistence.
374
+ - **Omitted**: votes are kept in component-local state only.
375
+
303
376
  ## Optional: Custom Workspace Settings
304
377
 
305
- By default, workspace settings (system prompt, context files, tools) are managed via the module's built-in UI and persisted by the Chat API service.
378
+ Agent-level configuration (system prompt, context files, tools, skills) lives in the workspace's Tela agent and is edited in the Tela app. The module's built-in settings UI manages knowledge sources (Tela workstations) and workspace credentials, persisted by the Chat API service.
306
379
 
307
- To override them, pass settings directly from your host app:
380
+ To override the settings the embed reads, pass them directly from your host app:
308
381
 
309
382
  ```vue
310
383
  <MeistrariChatEmbed
@@ -315,7 +388,6 @@ To override them, pass settings directly from your host app:
315
388
  canvasTools: null,
316
389
  knowledgeSources: null,
317
390
  externalSkills: null,
318
- createdAt: new Date(),
319
391
  updatedAt: new Date(),
320
392
  }"
321
393
  />
@@ -331,16 +403,22 @@ A skill that calls a host backend must implement its own callback contract with
331
403
 
332
404
  ## `<ChatConfigurationModal>`
333
405
 
334
- A reusable settings modal (system prompt, context files, Tela workstations, Tela skills, external skills, credentials) that any host app can open from any button. By default, the modal uses `useWorkspaceSettings()` to fetch and persist settings. If the host passes the `settings` prop, the host owns workspace settings state and persistence.
406
+ A reusable workspace settings modal that any host app can open from any button. It has three tabs:
407
+
408
+ - **`agent`** (Agente) — the workspace's Tela agent status. Shows the generic-chat state, the dedicated agent (id, copy, open in Tela), or — for workspaces whose legacy customization has not been migrated — a setup-required warning with a create-agent action. Agent configuration itself (system prompt, context files, tools, skills) is edited in the Tela app, not here.
409
+ - **`knowledge-sources`** (Tela workstations) — the workstations injected as knowledge sources into new chat sessions.
410
+ - **`credentials`** (Credenciais) — workspace credentials, shown when `showCredentialsTab` is set.
411
+
412
+ By default, the modal uses `useWorkspaceSettings()` to fetch and persist settings. If the host passes the `settings` prop, the host owns workspace settings state and persistence.
335
413
 
336
414
  ```vue
337
415
  <script setup lang="ts">
338
416
  import type { ChatConfigurationTab } from '@meistrari/chat-nuxt/types/workspace-settings'
339
417
 
340
418
  const open = ref(false)
341
- const initialTab = ref<ChatConfigurationTab>('personalization')
419
+ const initialTab = ref<ChatConfigurationTab>('agent')
342
420
 
343
- function openSettings(tab: ChatConfigurationTab = 'personalization') {
421
+ function openSettings(tab: ChatConfigurationTab = 'agent') {
344
422
  initialTab.value = tab
345
423
  open.value = true
346
424
  }
@@ -362,16 +440,16 @@ function openSettings(tab: ChatConfigurationTab = 'personalization') {
362
440
  |------|------|---------|-------------|
363
441
  | `open` | `boolean` | — | Modal visibility (supports `v-model:open`) |
364
442
  | `settings` | `WorkspaceSettings \| null` | `undefined` | Optional host-controlled settings. Omit this prop to let the modal fetch and persist via `useWorkspaceSettings()`; pass `null` or a settings object to make the host own state and persistence |
365
- | `initialTab` | `ChatConfigurationTab` | `'personalization'` | Tab to open on |
443
+ | `initialTab` | `ChatConfigurationTab` | `'agent'` | Tab to open on: `'agent' \| 'knowledge-sources' \| 'credentials'` |
366
444
  | `saving` | `boolean` | `false` | Host-controlled spinner/disable while persistence is in flight |
367
445
  | `showCredentialsTab` | `boolean` | `false` | Show the workspace credentials tab |
368
446
 
369
447
  | Event | Payload | Description |
370
448
  |-------|---------|-------------|
371
449
  | `update:open` | `boolean` | Modal open state changed |
372
- | `save` | `ChatConfigurationSavePayload` | Emitted only when the host passes `settings`; diff of the changed fields plus `onSaved`; host persists (e.g. via `useWorkspaceSettings().updateSettings()`), calls `onSaved` after persistence succeeds, and closes the modal |
450
+ | `save` | `ChatConfigurationSavePayload` | Emitted only when the host passes `settings`; carries the knowledge-source updates plus `onSaved`; host persists (e.g. via `useWorkspaceSettings().updateSettings()`), calls `onSaved` after persistence succeeds, and closes the modal |
373
451
 
374
- The `credentials` tab manages its own data via the module's `/api/workspace/credentials` endpoints and is never part of the `save` payload.
452
+ Only the knowledge-sources tab produces a `save` payload. The `agent` tab acts immediately through the module's `/api/workspace/agent` endpoints, and the `credentials` tab manages its own data via `/api/workspace/credentials` neither is part of the `save` payload.
375
453
 
376
454
  ## What's Included
377
455
 
@@ -388,17 +466,24 @@ Installing `@meistrari/chat-nuxt` installs the runtime packages used by the laye
388
466
  | Package | Version | Purpose |
389
467
  |---------|---------|---------|
390
468
  | `@meistrari/auth-nuxt` | `3.5.0` | Authentication (required) |
469
+ | `@meistrari/logger` | `^2.1.3` | Structured logging for the server proxy routes |
391
470
  | `@meistrari/tela-build` | `^1.30.0` | UI component library (Nuxt layer) |
392
471
  | `@sentry/nuxt` | `^10.0.0` | Client-side error capture used by chat composables |
393
- | `@iconify/vue` | `^5.0.0` | Icon rendering support |
472
+ | `@iconify/vue` + `@iconify-json/ph` | `^5.0.0` / `^1.2.2` | Icon rendering support (Phosphor set) |
394
473
  | `@vueuse/core` | `^12.8.0` | Runtime composables used by chat UI |
395
474
  | `@vueuse/components` | `^12.8.0` | VueUse component peer expected by the shared runtime |
475
+ | `beautiful-mermaid` + `mermaid` | `^1.1.3` / `^11.13.0` | Mermaid diagram rendering in markdown |
476
+ | `dompurify` | `^3.3.2` | HTML sanitization for rendered markdown |
396
477
  | `h3` | `^1.15.0` | Server route utilities provided by Nuxt/Nitro |
397
478
  | `markstream-vue` | `0.0.3-beta.6` | Markdown streaming renderer |
398
479
  | `motion` | `^11.13.0` | Animation component runtime |
399
480
  | `nitropack` | `^2.10.0` | Runtime config and task utilities provided by Nuxt/Nitro |
481
+ | `pdfjs-dist` | `^5.4.530` | PDF file previews |
482
+ | `posthog-js` | `^1.364.2` | Optional PostHog feature-flag helper |
400
483
  | `virtua` | `^0.42.0` | Virtualized list runtime expected by shared UI |
401
484
  | `vue-i18n` | `^11.0.0` | Internationalization runtime expected by shared UI |
485
+ | `xlsx` | `^0.18.5` | Spreadsheet file previews |
486
+ | `zod` | `^4.1.13` | Schema validation for API payloads |
402
487
 
403
488
  Peer dependencies:
404
489
 
package/dist/module.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- export { ChatActionPayload, ChatActor, ChatEmbedSharedProps, ChatFeatureConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, TelaAgentChatEmbedProps, TelaAgentExecutionInput } from '../dist/runtime/types/embed.js';
1
+ export { ChatActionPayload, ChatActor, ChatEmbedSharedProps, ChatFeatureConfig, ChatSidebarConfig, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, TelaAgentChatEmbedProps, TelaAgentExecutionInput } from '../dist/runtime/types/embed.js';
2
2
 
3
3
  type ChatNuxtConfigValidationMode = false | 'warn' | 'error';
4
4
 
package/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meistrari/chat-nuxt",
3
3
  "configKey": "chatNuxt",
4
- "version": "3.0.0",
4
+ "version": "3.2.0",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -2,25 +2,20 @@
2
2
  import { useBreakpoints, useMagicKeys } from "@vueuse/core";
3
3
  import { CHAT_MOBILE_BREAKPOINT } from "../../shared/breakpoints";
4
4
  import ChatConfigurationMobileShell from "./configuration/chat-configuration-mobile-shell.vue";
5
- import { useFileUpload } from "../../files/composables/file-upload";
6
5
  import { useKnowledgeSources } from "../../workspace/composables/knowledge-sources";
7
6
  import { useStatusToast } from "../../shared/composables/status-toast";
8
7
  import { useTela } from "../../shared/composables/tela";
9
- import { useWorkspaceContextFiles } from "../../workspace/composables/workspace-context-files";
10
- import { useWorkspaceExternalSkills } from "../../workspace/composables/workspace-external-skills";
8
+ import { useWorkspaceAgent } from "../../workspace/composables/workspace-agent";
11
9
  import { useWorkspaceKnowledgeSources } from "../../workspace/composables/workspace-knowledge-sources";
12
- import { useWorkspacePersonalization } from "../../workspace/composables/workspace-personalization";
13
10
  import { useWorkspaceSettings } from "../../workspace/composables/workspace-settings";
14
- import { useWorkspaceTelaTools } from "../../workspace/composables/workspace-tela-tools";
15
11
  const props = defineProps({
16
12
  open: { type: Boolean, required: true },
17
13
  settings: { type: null, required: false },
18
- initialTab: { type: String, required: false, default: "personalization" },
14
+ initialTab: { type: String, required: false, default: "agent" },
19
15
  saving: { type: Boolean, required: false, default: false },
20
16
  showCredentialsTab: { type: Boolean, required: false, default: false }
21
17
  });
22
18
  const emit = defineEmits(["update:open", "save"]);
23
- const { uploadFiles, uploading } = useFileUpload();
24
19
  const { canvas, projects, workstations, loadingWorkstations } = useTela();
25
20
  const { setKnowledgeSources } = useKnowledgeSources();
26
21
  const statusToast = useStatusToast();
@@ -33,6 +28,7 @@ const {
33
28
  fetchSettings,
34
29
  updateSettings
35
30
  } = useWorkspaceSettings();
31
+ const workspaceAgent = useWorkspaceAgent();
36
32
  const searchQuery = ref("");
37
33
  const activeTab = ref(props.initialTab);
38
34
  const activeMobileTab = ref(null);
@@ -40,29 +36,15 @@ const showDiscardConfirm = ref(false);
40
36
  const loadingInitialSettings = ref(false);
41
37
  const hasSettingsOverride = computed(() => props.settings !== void 0);
42
38
  const mutableSettings = computed(() => hasSettingsOverride.value ? props.settings : workspaceSettings.value);
43
- const currentSystemMessage = computed(() => mutableSettings.value?.systemMessage ?? null);
44
- const currentContextFiles = computed(() => mutableSettings.value?.contextFiles ?? null);
45
- const currentCanvasTools = computed(() => mutableSettings.value?.canvasTools ?? null);
46
39
  const currentKnowledgeSources = computed(() => mutableSettings.value?.knowledgeSources ?? null);
47
- const currentExternalSkills = computed(() => mutableSettings.value?.externalSkills ?? null);
48
- const personalization = useWorkspacePersonalization(currentSystemMessage);
49
- const telaTools = useWorkspaceTelaTools(canvas, projects, searchQuery, currentCanvasTools);
50
40
  const knowledgeSources = useWorkspaceKnowledgeSources(workstations, canvas, projects, searchQuery, currentKnowledgeSources);
51
- const contextFiles = useWorkspaceContextFiles(searchQuery, currentContextFiles);
52
- const externalSkills = useWorkspaceExternalSkills(currentExternalSkills, searchQuery);
53
41
  const settingsTabs = computed(() => [
54
- { value: "personalization", label: "Personaliza\xE7\xE3o", icon: "i-ph-sliders" },
55
- { value: "context-files", label: "Arquivos de contexto", icon: "i-ph-file-text" },
42
+ { value: "agent", label: "Agente", icon: "i-ph-robot" },
56
43
  { value: "knowledge-sources", label: "Tela workstations", icon: "i-ph-database" },
57
- { value: "tela-tools", label: "Skills Tela", icon: "i-ph-puzzle-piece" },
58
- { value: "external-skills", label: "Skills Externas", icon: "i-ph-wrench" },
59
44
  ...props.showCredentialsTab ? [{ value: "credentials", label: "Credenciais", icon: "i-ph-password-bold" }] : []
60
45
  ]);
61
- const hasChanges = computed(
62
- () => personalization.hasChanges.value || contextFiles.hasChanges.value || telaTools.hasChanges.value || knowledgeSources.hasChanges.value || externalSkills.hasChanges.value
63
- );
64
- const isBusy = computed(() => props.saving || uploading.value || !hasSettingsOverride.value && workspaceSettingsLoading.value);
65
- const gitHubButtonText = computed(() => externalSkills.getGitHubButtonText());
46
+ const hasChanges = computed(() => knowledgeSources.hasChanges.value);
47
+ const isBusy = computed(() => props.saving || !hasSettingsOverride.value && workspaceSettingsLoading.value);
66
48
  watch(() => escape?.value, (pressed) => {
67
49
  if (pressed && props.open && !showDiscardConfirm.value)
68
50
  handleClose();
@@ -72,11 +54,12 @@ watch(() => props.open, (isOpen) => {
72
54
  searchQuery.value = "";
73
55
  activateTab(props.initialTab);
74
56
  activeMobileTab.value = null;
57
+ void loadAgentStatus();
75
58
  if (!hasSettingsOverride.value && !mutableSettings.value) {
76
59
  void loadSettings();
77
60
  return;
78
61
  }
79
- initializeConfigurationState();
62
+ knowledgeSources.initialize();
80
63
  } else {
81
64
  loadingInitialSettings.value = false;
82
65
  }
@@ -85,27 +68,14 @@ watch(() => props.initialTab, (tab) => {
85
68
  if (props.open)
86
69
  activateTab(tab);
87
70
  });
88
- watch(currentSystemMessage, () => {
89
- if (props.open)
90
- personalization.initialize();
91
- });
92
71
  watch(mutableSettings, (settings, previousSettings) => {
93
72
  if (props.open && hasSettingsOverride.value && settings && !previousSettings)
94
- initializeConfigurationState();
73
+ knowledgeSources.initialize();
95
74
  });
96
- function initializeConfigurationState() {
97
- personalization.initialize();
98
- telaTools.initialize();
99
- knowledgeSources.initialize();
100
- contextFiles.initialize();
101
- externalSkills.initialize();
102
- }
103
75
  function activateTab(tab) {
104
76
  const isVisible = settingsTabs.value.some((t) => t.value === tab);
105
- activeTab.value = isVisible ? tab : "personalization";
77
+ activeTab.value = isVisible ? tab : "agent";
106
78
  searchQuery.value = "";
107
- if (activeTab.value === "external-skills")
108
- void externalSkills.fetchGitHubConnection();
109
79
  }
110
80
  function activateMobileTab(tab) {
111
81
  activateTab(tab);
@@ -115,7 +85,7 @@ async function loadSettings() {
115
85
  loadingInitialSettings.value = true;
116
86
  try {
117
87
  await fetchSettings();
118
- initializeConfigurationState();
88
+ knowledgeSources.initialize();
119
89
  } catch (error) {
120
90
  console.error("Failed to load workspace settings:", error);
121
91
  statusToast.update({
@@ -126,44 +96,47 @@ async function loadSettings() {
126
96
  loadingInitialSettings.value = false;
127
97
  }
128
98
  }
99
+ async function loadAgentStatus() {
100
+ try {
101
+ await workspaceAgent.fetchStatus();
102
+ } catch (error) {
103
+ console.error("Failed to load workspace agent status:", error);
104
+ statusToast.update({
105
+ text: "Erro ao carregar o status do agente",
106
+ icon: "i-ph-warning"
107
+ });
108
+ }
109
+ }
110
+ async function handleCreateAgent() {
111
+ try {
112
+ const status = await workspaceAgent.createAgent();
113
+ if (!status)
114
+ return;
115
+ statusToast.update({
116
+ text: "Agente criado no Tela",
117
+ icon: "i-ph-check"
118
+ });
119
+ if (status.telaAgentUrl)
120
+ window.open(status.telaAgentUrl, "_blank", "noopener");
121
+ } catch (error) {
122
+ console.error("Failed to create workspace agent:", error);
123
+ statusToast.update({
124
+ text: "Erro ao criar o agente no Tela",
125
+ icon: "i-ph-warning"
126
+ });
127
+ }
128
+ }
129
129
  async function handleSave() {
130
130
  if (!hasChanges.value || isBusy.value)
131
131
  return;
132
132
  try {
133
- const updates = {};
134
- if (personalization.hasChanges.value)
135
- updates.systemMessage = personalization.getSystemMessage();
136
- if (contextFiles.hasChanges.value) {
137
- const pendingFilesList = contextFiles.getPendingFiles();
138
- const uploadedFiles = pendingFilesList.length > 0 ? await uploadFiles(pendingFilesList) : [];
139
- const newContextFiles = [
140
- ...contextFiles.getKeptContextFiles(),
141
- ...uploadedFiles.map((f) => ({ url: f.url, name: f.name, mimeType: f.mimeType }))
142
- ];
143
- updates.contextFiles = newContextFiles.length > 0 ? newContextFiles : null;
144
- }
145
- if (telaTools.hasChanges.value) {
146
- const tools = telaTools.buildCanvasTools();
147
- updates.canvasTools = tools.length > 0 ? tools : null;
148
- }
149
- let pendingKnowledgeSources = null;
150
- if (knowledgeSources.hasChanges.value) {
151
- const sources = knowledgeSources.buildKnowledgeSources();
152
- updates.knowledgeSources = sources.length > 0 ? sources : null;
153
- pendingKnowledgeSources = sources.length > 0 ? sources : null;
154
- }
155
- if (externalSkills.hasChanges.value)
156
- updates.externalSkills = externalSkills.buildExternalSkills();
157
- const shouldUpdateKnowledgeSources = pendingKnowledgeSources !== null || knowledgeSources.hasChanges.value;
158
- const shouldClearContextFiles = contextFiles.hasChanges.value;
159
- const shouldResetExternalSkills = externalSkills.hasChanges.value;
133
+ const sources = knowledgeSources.buildKnowledgeSources();
134
+ const pendingKnowledgeSources = sources.length > 0 ? sources : null;
135
+ const updates = {
136
+ knowledgeSources: pendingKnowledgeSources
137
+ };
160
138
  const onSaved = () => {
161
- if (shouldUpdateKnowledgeSources)
162
- setKnowledgeSources(pendingKnowledgeSources);
163
- if (shouldClearContextFiles)
164
- contextFiles.clearPendingFiles();
165
- if (shouldResetExternalSkills)
166
- externalSkills.initialize();
139
+ setKnowledgeSources(pendingKnowledgeSources);
167
140
  };
168
141
  if (hasSettingsOverride.value) {
169
142
  emit("save", { updates, onSaved });
@@ -224,23 +197,12 @@ function cancelDiscard() {
224
197
  </p>
225
198
  </div>
226
199
 
227
- <ChatConfigurationPersonalizationTab
228
- v-else-if="activeTab === 'personalization'"
229
- v-model:system-message="personalization.localSystemMessage.value"
230
- />
231
-
232
- <ChatConfigurationContextFilesTab
233
- v-else-if="activeTab === 'context-files'"
234
- :search-query="searchQuery"
235
- :filtered-context-files="contextFiles.filteredContextFiles.value"
236
- :filtered-pending-files="contextFiles.filteredPendingFiles.value"
237
- :current-file-count="contextFiles.currentFileCount.value"
238
- :max-files="contextFiles.maxFiles"
239
- :get-file-type="contextFiles.getFileType"
240
- @update:search-query="searchQuery = $event"
241
- @handle-file-select="contextFiles.handleFileSelect"
242
- @remove-pending-file="contextFiles.removePendingFile"
243
- @remove-context-file="contextFiles.removeContextFile"
200
+ <ChatConfigurationAgentTab
201
+ v-else-if="activeTab === 'agent'"
202
+ :status="workspaceAgent.status.value"
203
+ :loading="workspaceAgent.loading.value"
204
+ :creating="workspaceAgent.creating.value"
205
+ @create="handleCreateAgent"
244
206
  />
245
207
 
246
208
  <ChatConfigurationKnowledgeSourcesTab
@@ -255,40 +217,6 @@ function cancelDiscard() {
255
217
  @toggle="knowledgeSources.toggleKnowledgeSource"
256
218
  />
257
219
 
258
- <ChatConfigurationTelaToolsTab
259
- v-else-if="activeTab === 'tela-tools'"
260
- :search-query="searchQuery"
261
- :canvas="canvas"
262
- :filtered-canvas-tools="telaTools.filteredCanvasTools.value"
263
- :selected-tool-ids="telaTools.selectedToolIds.value"
264
- :all-tools-selected="telaTools.allToolsSelected.value"
265
- :get-project-name="telaTools.getProjectName"
266
- @update:search-query="searchQuery = $event"
267
- @toggle-tool="telaTools.toggleCanvasTool"
268
- @toggle-all="telaTools.toggleAllTools"
269
- />
270
-
271
- <ChatConfigurationExternalSkillsTab
272
- v-else-if="activeTab === 'external-skills'"
273
- :search-query="searchQuery"
274
- :displayed-skills="externalSkills.displayedSkills.value"
275
- :filtered-skills="externalSkills.filteredSkills.value"
276
- :has-changes="externalSkills.hasChanges.value"
277
- :is-pending="externalSkills.isPending"
278
- :skill-modal-open="externalSkills.skillModalOpen.value"
279
- :skill-ref-input="externalSkills.skillRefInput.value"
280
- :skill-error="externalSkills.skillError.value"
281
- :discovering-skills="externalSkills.discoveringSkills.value"
282
- :git-hub-button-text="gitHubButtonText"
283
- @update:search-query="searchQuery = $event"
284
- @update:skill-modal-open="externalSkills.skillModalOpen.value = $event"
285
- @update:skill-ref-input="externalSkills.skillRefInput.value = $event"
286
- @remove-skill="externalSkills.removeSkill"
287
- @close-skill-modal="externalSkills.closeSkillModal"
288
- @handle-add-skill-and-close="externalSkills.handleAddSkillAndClose"
289
- @connect-git-hub="externalSkills.connectGitHub"
290
- />
291
-
292
220
  <ChatConfigurationCredentialsTab
293
221
  v-else-if="activeTab === 'credentials' && props.showCredentialsTab"
294
222
  :search-query="searchQuery"
@@ -388,23 +316,12 @@ function cancelDiscard() {
388
316
  </p>
389
317
  </div>
390
318
 
391
- <ChatConfigurationPersonalizationTab
392
- v-else-if="activeTab === 'personalization'"
393
- v-model:system-message="personalization.localSystemMessage.value"
394
- />
395
-
396
- <ChatConfigurationContextFilesTab
397
- v-else-if="activeTab === 'context-files'"
398
- :search-query="searchQuery"
399
- :filtered-context-files="contextFiles.filteredContextFiles.value"
400
- :filtered-pending-files="contextFiles.filteredPendingFiles.value"
401
- :current-file-count="contextFiles.currentFileCount.value"
402
- :max-files="contextFiles.maxFiles"
403
- :get-file-type="contextFiles.getFileType"
404
- @update:search-query="searchQuery = $event"
405
- @handle-file-select="contextFiles.handleFileSelect"
406
- @remove-pending-file="contextFiles.removePendingFile"
407
- @remove-context-file="contextFiles.removeContextFile"
319
+ <ChatConfigurationAgentTab
320
+ v-else-if="activeTab === 'agent'"
321
+ :status="workspaceAgent.status.value"
322
+ :loading="workspaceAgent.loading.value"
323
+ :creating="workspaceAgent.creating.value"
324
+ @create="handleCreateAgent"
408
325
  />
409
326
 
410
327
  <ChatConfigurationKnowledgeSourcesTab
@@ -419,40 +336,6 @@ function cancelDiscard() {
419
336
  @toggle="knowledgeSources.toggleKnowledgeSource"
420
337
  />
421
338
 
422
- <ChatConfigurationTelaToolsTab
423
- v-else-if="activeTab === 'tela-tools'"
424
- :search-query="searchQuery"
425
- :canvas="canvas"
426
- :filtered-canvas-tools="telaTools.filteredCanvasTools.value"
427
- :selected-tool-ids="telaTools.selectedToolIds.value"
428
- :all-tools-selected="telaTools.allToolsSelected.value"
429
- :get-project-name="telaTools.getProjectName"
430
- @update:search-query="searchQuery = $event"
431
- @toggle-tool="telaTools.toggleCanvasTool"
432
- @toggle-all="telaTools.toggleAllTools"
433
- />
434
-
435
- <ChatConfigurationExternalSkillsTab
436
- v-else-if="activeTab === 'external-skills'"
437
- :search-query="searchQuery"
438
- :displayed-skills="externalSkills.displayedSkills.value"
439
- :filtered-skills="externalSkills.filteredSkills.value"
440
- :has-changes="externalSkills.hasChanges.value"
441
- :is-pending="externalSkills.isPending"
442
- :skill-modal-open="externalSkills.skillModalOpen.value"
443
- :skill-ref-input="externalSkills.skillRefInput.value"
444
- :skill-error="externalSkills.skillError.value"
445
- :discovering-skills="externalSkills.discoveringSkills.value"
446
- :git-hub-button-text="gitHubButtonText"
447
- @update:search-query="searchQuery = $event"
448
- @update:skill-modal-open="externalSkills.skillModalOpen.value = $event"
449
- @update:skill-ref-input="externalSkills.skillRefInput.value = $event"
450
- @remove-skill="externalSkills.removeSkill"
451
- @close-skill-modal="externalSkills.closeSkillModal"
452
- @handle-add-skill-and-close="externalSkills.handleAddSkillAndClose"
453
- @connect-git-hub="externalSkills.connectGitHub"
454
- />
455
-
456
339
  <ChatConfigurationCredentialsTab
457
340
  v-else-if="activeTab === 'credentials' && props.showCredentialsTab"
458
341
  :search-query="searchQuery"
@@ -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
+ };