@meistrari/chat-nuxt 1.1.2 → 1.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.
- package/README.md +95 -11
- package/dist/module.d.mts +5 -0
- package/dist/module.json +2 -2
- package/dist/module.mjs +96 -23
- package/dist/runtime/components/chat/conversation-list.d.vue.ts +1 -0
- package/dist/runtime/components/chat/conversation-list.vue +22 -2
- package/dist/runtime/components/chat/conversation-list.vue.d.ts +1 -0
- package/dist/runtime/components/chat/message-list.d.vue.ts +1 -0
- package/dist/runtime/components/chat/message-list.vue +23 -2
- package/dist/runtime/components/chat/message-list.vue.d.ts +1 -0
- package/dist/runtime/composables/useChat.d.ts +2 -1
- package/dist/runtime/composables/useChat.js +32 -3
- package/dist/runtime/composables/useChatApi.js +2 -1
- package/dist/runtime/composables/useConversations.d.ts +3 -2
- package/dist/runtime/composables/useConversations.js +99 -11
- package/dist/runtime/composables/useEmbedConfig.d.ts +11 -6
- package/dist/runtime/composables/useEmbedConfig.js +35 -7
- package/dist/runtime/composables/useIDB.js +4 -0
- package/dist/runtime/composables/usePdf.d.ts +840 -1
- package/dist/runtime/composables/usePdf.js +21 -3
- package/dist/runtime/composables/useWorkspaceContextFiles.d.ts +3 -3
- package/dist/runtime/composables/useWorkspaceContextFiles.js +19 -10
- package/dist/runtime/composables/useWorkspaceCredentials.d.ts +3 -3
- package/dist/runtime/composables/useWorkspaceExternalSkills.d.ts +1 -1
- package/dist/runtime/composables/useWorkspaceExternalSkills.js +5 -6
- package/dist/runtime/composables/useWorkspacePersonalization.d.ts +1 -1
- package/dist/runtime/composables/useWorkspacePersonalization.js +4 -5
- package/dist/runtime/composables/useWorkspaceSettings.js +12 -9
- package/dist/runtime/embed/components/ChatConfigurationModal.d.vue.ts +25 -0
- package/dist/runtime/embed/components/ChatConfigurationModal.vue +373 -0
- package/dist/runtime/embed/components/ChatConfigurationModal.vue.d.ts +25 -0
- package/dist/runtime/embed/components/ChatEmbed.vue +12 -1
- package/dist/runtime/embed/components/ChatEmbedInner.vue +31 -16
- package/dist/runtime/embed/components/configuration/ChatConfigurationContextFilesTab.d.vue.ts +22 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationContextFilesTab.vue +133 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationContextFilesTab.vue.d.ts +22 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationCredentialsTab.d.vue.ts +10 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationCredentialsTab.vue +220 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationCredentialsTab.vue.d.ts +10 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationExternalSkillsTab.d.vue.ts +32 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationExternalSkillsTab.vue +222 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationExternalSkillsTab.vue.d.ts +32 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationKnowledgeSourcesTab.d.vue.ts +18 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationKnowledgeSourcesTab.vue +142 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationKnowledgeSourcesTab.vue.d.ts +18 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationPersonalizationTab.d.vue.ts +10 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationPersonalizationTab.vue +37 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationPersonalizationTab.vue.d.ts +10 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationTelaToolsTab.d.vue.ts +20 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationTelaToolsTab.vue +146 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationTelaToolsTab.vue.d.ts +20 -0
- package/dist/runtime/server/api/admin/trigger-usage-report.post.d.ts +4 -1
- package/dist/runtime/server/api/admin/trigger-usage-report.post.js +2 -0
- package/dist/runtime/server/api/chat/workspace/settings.get.d.ts +1 -1
- package/dist/runtime/server/api/chat/workspace/settings.get.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/cancel.post.d.ts +4 -1
- package/dist/runtime/server/api/conversations/[id]/cancel.post.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/clear.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/clear.post.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/duplicate.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/duplicate.post.js +46 -12
- package/dist/runtime/server/api/conversations/[id]/files.get.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/files.get.js +2 -0
- package/dist/runtime/server/api/conversations/[id]/index.delete.d.ts +3 -1
- package/dist/runtime/server/api/conversations/[id]/index.delete.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/index.get.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/index.get.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/index.patch.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/index.patch.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +2 -0
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.d.ts +14 -1
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.js +2 -0
- package/dist/runtime/server/api/conversations/[id]/messages/index.post.d.ts +4 -1
- package/dist/runtime/server/api/conversations/[id]/messages/index.post.js +2 -0
- package/dist/runtime/server/api/conversations/[id]/usage.get.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/usage.get.js +1 -0
- package/dist/runtime/server/api/conversations/generate-title.post.d.ts +3 -1
- package/dist/runtime/server/api/conversations/generate-title.post.js +2 -0
- package/dist/runtime/server/api/conversations/index.get.d.ts +1 -1
- package/dist/runtime/server/api/conversations/index.get.js +1 -0
- package/dist/runtime/server/api/conversations/index.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/index.post.js +1 -0
- package/dist/runtime/server/api/external-skills/discover.post.d.ts +1 -1
- package/dist/runtime/server/api/external-skills/discover.post.js +2 -0
- package/dist/runtime/server/api/github/disconnect.post.d.ts +3 -1
- package/dist/runtime/server/api/github/disconnect.post.js +2 -0
- package/dist/runtime/server/api/github/status.get.d.ts +1 -1
- package/dist/runtime/server/api/github/status.get.js +2 -0
- package/dist/runtime/server/api/tela/canvas.get.d.ts +1 -1
- package/dist/runtime/server/api/tela/canvas.get.js +1 -0
- package/dist/runtime/server/api/tela/projects.get.d.ts +1 -1
- package/dist/runtime/server/api/tela/projects.get.js +1 -0
- package/dist/runtime/server/api/tela/workspaces.get.d.ts +1 -1
- package/dist/runtime/server/api/tela/workspaces.get.js +1 -0
- package/dist/runtime/server/api/tela/workstations.get.d.ts +1 -1
- package/dist/runtime/server/api/tela/workstations.get.js +1 -0
- package/dist/runtime/server/api/vault/permalink-metadata.post.d.ts +5 -1
- package/dist/runtime/server/api/vault/permalink-metadata.post.js +2 -0
- package/dist/runtime/server/api/vault/resolve.post.d.ts +9 -1
- package/dist/runtime/server/api/vault/resolve.post.js +2 -0
- package/dist/runtime/server/api/vault/upload.post.d.ts +6 -1
- package/dist/runtime/server/api/vault/upload.post.js +2 -0
- package/dist/runtime/server/api/workspace/credentials/[id].delete.d.ts +3 -1
- package/dist/runtime/server/api/workspace/credentials/[id].delete.js +1 -0
- package/dist/runtime/server/api/workspace/credentials/[id].put.d.ts +1 -1
- package/dist/runtime/server/api/workspace/credentials/[id].put.js +1 -0
- package/dist/runtime/server/api/workspace/credentials/index.get.d.ts +1 -1
- package/dist/runtime/server/api/workspace/credentials/index.get.js +1 -0
- package/dist/runtime/server/api/workspace/credentials/index.post.d.ts +1 -1
- package/dist/runtime/server/api/workspace/credentials/index.post.js +1 -0
- package/dist/runtime/server/api/workspace/settings.get.d.ts +1 -1
- package/dist/runtime/server/api/workspace/settings.get.js +1 -0
- package/dist/runtime/server/api/workspace/settings.patch.d.ts +1 -1
- package/dist/runtime/server/api/workspace/settings.patch.js +1 -0
- package/dist/runtime/server/api/workspace/usage.get.d.ts +1 -1
- package/dist/runtime/server/api/workspace/usage.get.js +1 -0
- package/dist/runtime/server/db/index.js +1 -0
- package/dist/runtime/server/middleware/domain-validation.d.ts +1 -1
- package/dist/runtime/server/middleware/domain-validation.js +2 -0
- package/dist/runtime/server/middleware/request-logger.d.ts +1 -1
- package/dist/runtime/server/middleware/request-logger.js +1 -0
- package/dist/runtime/server/tasks/send-daily-usage-report.d.ts +1 -1
- package/dist/runtime/server/tasks/send-daily-usage-report.js +1 -0
- package/dist/runtime/server/utils/agent-api.d.ts +1 -1
- package/dist/runtime/server/utils/agent-api.js +2 -0
- package/dist/runtime/server/utils/auth-api.js +2 -0
- package/dist/runtime/server/utils/auth.d.ts +1 -1
- package/dist/runtime/server/utils/auth.js +1 -0
- package/dist/runtime/server/utils/tela-api.d.ts +1 -1
- package/dist/runtime/server/utils/tela-api.js +2 -0
- package/dist/runtime/server/utils/workspace.js +1 -0
- package/dist/runtime/types/chat.d.ts +2 -1
- package/dist/runtime/types/workspace-settings.d.ts +3 -0
- package/dist/runtime/types/workspace-settings.js +0 -0
- package/dist/runtime/utils/conversation-list-skeleton.d.ts +31 -0
- package/dist/runtime/utils/conversation-list-skeleton.js +12 -0
- package/dist/runtime/utils/file.js +42 -42
- package/dist/types.d.mts +2 -0
- package/package.json +24 -12
- package/dist/runtime/composables/PageNavigation.d.ts +0 -13
- package/dist/runtime/composables/PageNavigation.js +0 -18
- /package/dist/runtime/components/{TelaChat.d.vue.ts → MeistrariChatEmbed.d.vue.ts} +0 -0
- /package/dist/runtime/components/{TelaChat.vue → MeistrariChatEmbed.vue} +0 -0
- /package/dist/runtime/components/{TelaChat.vue.d.ts → MeistrariChatEmbed.vue.d.ts} +0 -0
- /package/dist/runtime/components/{pdf-preview.d.vue.ts → pdf-preview.client.d.vue.ts} +0 -0
- /package/dist/runtime/components/{pdf-preview.vue → pdf-preview.client.vue} +0 -0
- /package/dist/runtime/components/{pdf-preview.vue.d.ts → pdf-preview.client.vue.d.ts} +0 -0
- /package/dist/runtime/components/{pdf-viewer.d.vue.ts → pdf-viewer.client.d.vue.ts} +0 -0
- /package/dist/runtime/components/{pdf-viewer.vue → pdf-viewer.client.vue} +0 -0
- /package/dist/runtime/components/{pdf-viewer.vue.d.ts → pdf-viewer.client.vue.d.ts} +0 -0
|
@@ -0,0 +1,373 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { useMagicKeys } from "@vueuse/core";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
open: { type: Boolean, required: true },
|
|
5
|
+
settings: { type: null, required: false },
|
|
6
|
+
initialTab: { type: String, required: false, default: "personalization" },
|
|
7
|
+
saving: { type: Boolean, required: false, default: false }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["update:open", "save"]);
|
|
10
|
+
const { uploadFiles, uploading } = useFileUpload();
|
|
11
|
+
const { canvas, projects, workstations, loadingWorkstations } = useTela();
|
|
12
|
+
const { setKnowledgeSources } = useKnowledgeSources();
|
|
13
|
+
const statusToast = useStatusToast();
|
|
14
|
+
const { escape } = useMagicKeys();
|
|
15
|
+
const {
|
|
16
|
+
settings: workspaceSettings,
|
|
17
|
+
loading: workspaceSettingsLoading,
|
|
18
|
+
fetchSettings,
|
|
19
|
+
updateSettings
|
|
20
|
+
} = useWorkspaceSettings();
|
|
21
|
+
const searchQuery = ref("");
|
|
22
|
+
const activeTab = ref(props.initialTab);
|
|
23
|
+
const showDiscardConfirm = ref(false);
|
|
24
|
+
const loadingInitialSettings = ref(false);
|
|
25
|
+
const hasSettingsOverride = computed(() => props.settings !== void 0);
|
|
26
|
+
const mutableSettings = computed(() => hasSettingsOverride.value ? props.settings : workspaceSettings.value);
|
|
27
|
+
const currentSystemMessage = computed(() => mutableSettings.value?.systemMessage ?? null);
|
|
28
|
+
const currentContextFiles = computed(() => mutableSettings.value?.contextFiles ?? null);
|
|
29
|
+
const currentCanvasTools = computed(() => mutableSettings.value?.canvasTools ?? null);
|
|
30
|
+
const currentKnowledgeSources = computed(() => mutableSettings.value?.knowledgeSources ?? null);
|
|
31
|
+
const currentExternalSkills = computed(() => mutableSettings.value?.externalSkills ?? null);
|
|
32
|
+
const personalization = useWorkspacePersonalization(currentSystemMessage);
|
|
33
|
+
const telaTools = useWorkspaceTelaTools(canvas, projects, searchQuery, currentCanvasTools);
|
|
34
|
+
const knowledgeSources = useWorkspaceKnowledgeSources(workstations, canvas, projects, searchQuery, currentKnowledgeSources);
|
|
35
|
+
const contextFiles = useWorkspaceContextFiles(searchQuery, currentContextFiles);
|
|
36
|
+
const externalSkills = useWorkspaceExternalSkills(currentExternalSkills, searchQuery);
|
|
37
|
+
const settingsTabs = [
|
|
38
|
+
{ value: "personalization", label: "Personaliza\xE7\xE3o", icon: "i-ph-sliders" },
|
|
39
|
+
{ value: "context-files", label: "Arquivos de contexto", icon: "i-ph-file-text" },
|
|
40
|
+
{ value: "knowledge-sources", label: "Tela workstations", icon: "i-ph-database" },
|
|
41
|
+
{ value: "tela-tools", label: "Skills Tela", icon: "i-ph-puzzle-piece" },
|
|
42
|
+
{ value: "external-skills", label: "Skills Externas", icon: "i-ph-wrench" },
|
|
43
|
+
{ value: "credentials", label: "Credenciais", icon: "i-ph-password-bold" }
|
|
44
|
+
];
|
|
45
|
+
const hasChanges = computed(
|
|
46
|
+
() => personalization.hasChanges.value || contextFiles.hasChanges.value || telaTools.hasChanges.value || knowledgeSources.hasChanges.value || externalSkills.hasChanges.value
|
|
47
|
+
);
|
|
48
|
+
const isBusy = computed(() => props.saving || uploading.value || !hasSettingsOverride.value && workspaceSettingsLoading.value);
|
|
49
|
+
const gitHubButtonText = computed(() => externalSkills.getGitHubButtonText());
|
|
50
|
+
watch(() => escape?.value, (pressed) => {
|
|
51
|
+
if (pressed && props.open && !showDiscardConfirm.value)
|
|
52
|
+
handleClose();
|
|
53
|
+
});
|
|
54
|
+
watch(() => props.open, (isOpen) => {
|
|
55
|
+
if (isOpen) {
|
|
56
|
+
searchQuery.value = "";
|
|
57
|
+
activateTab(props.initialTab);
|
|
58
|
+
if (!hasSettingsOverride.value && !mutableSettings.value) {
|
|
59
|
+
void loadSettings();
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
initializeConfigurationState();
|
|
63
|
+
} else {
|
|
64
|
+
loadingInitialSettings.value = false;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
watch(() => props.initialTab, (tab) => {
|
|
68
|
+
if (props.open)
|
|
69
|
+
activateTab(tab);
|
|
70
|
+
});
|
|
71
|
+
watch(currentSystemMessage, () => {
|
|
72
|
+
if (props.open)
|
|
73
|
+
personalization.initialize();
|
|
74
|
+
});
|
|
75
|
+
watch(mutableSettings, (settings, previousSettings) => {
|
|
76
|
+
if (props.open && hasSettingsOverride.value && settings && !previousSettings)
|
|
77
|
+
initializeConfigurationState();
|
|
78
|
+
});
|
|
79
|
+
function initializeConfigurationState() {
|
|
80
|
+
personalization.initialize();
|
|
81
|
+
telaTools.initialize();
|
|
82
|
+
knowledgeSources.initialize();
|
|
83
|
+
contextFiles.initialize();
|
|
84
|
+
externalSkills.initialize();
|
|
85
|
+
}
|
|
86
|
+
function activateTab(tab) {
|
|
87
|
+
activeTab.value = tab;
|
|
88
|
+
searchQuery.value = "";
|
|
89
|
+
if (tab === "external-skills")
|
|
90
|
+
void externalSkills.fetchGitHubConnection();
|
|
91
|
+
}
|
|
92
|
+
async function loadSettings() {
|
|
93
|
+
loadingInitialSettings.value = true;
|
|
94
|
+
try {
|
|
95
|
+
await fetchSettings();
|
|
96
|
+
initializeConfigurationState();
|
|
97
|
+
} catch (error) {
|
|
98
|
+
console.error("Failed to load workspace settings:", error);
|
|
99
|
+
statusToast.update({
|
|
100
|
+
text: "Erro ao carregar configura\xE7\xF5es",
|
|
101
|
+
icon: "i-ph-warning"
|
|
102
|
+
});
|
|
103
|
+
} finally {
|
|
104
|
+
loadingInitialSettings.value = false;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async function handleSave() {
|
|
108
|
+
if (!hasChanges.value || isBusy.value)
|
|
109
|
+
return;
|
|
110
|
+
try {
|
|
111
|
+
const updates = {};
|
|
112
|
+
if (personalization.hasChanges.value)
|
|
113
|
+
updates.systemMessage = personalization.getSystemMessage();
|
|
114
|
+
if (contextFiles.hasChanges.value) {
|
|
115
|
+
const pendingFilesList = contextFiles.getPendingFiles();
|
|
116
|
+
const uploadedFiles = pendingFilesList.length > 0 ? await uploadFiles(pendingFilesList) : [];
|
|
117
|
+
const newContextFiles = [
|
|
118
|
+
...contextFiles.getKeptContextFiles(),
|
|
119
|
+
...uploadedFiles.map((f) => ({ url: f.url, name: f.name, mimeType: f.mimeType }))
|
|
120
|
+
];
|
|
121
|
+
updates.contextFiles = newContextFiles.length > 0 ? newContextFiles : null;
|
|
122
|
+
}
|
|
123
|
+
if (telaTools.hasChanges.value) {
|
|
124
|
+
const tools = telaTools.buildCanvasTools();
|
|
125
|
+
updates.canvasTools = tools.length > 0 ? tools : null;
|
|
126
|
+
}
|
|
127
|
+
let pendingKnowledgeSources = null;
|
|
128
|
+
if (knowledgeSources.hasChanges.value) {
|
|
129
|
+
const sources = knowledgeSources.buildKnowledgeSources();
|
|
130
|
+
updates.knowledgeSources = sources.length > 0 ? sources : null;
|
|
131
|
+
pendingKnowledgeSources = sources.length > 0 ? sources : null;
|
|
132
|
+
}
|
|
133
|
+
if (externalSkills.hasChanges.value)
|
|
134
|
+
updates.externalSkills = externalSkills.buildExternalSkills();
|
|
135
|
+
const shouldUpdateKnowledgeSources = pendingKnowledgeSources !== null || knowledgeSources.hasChanges.value;
|
|
136
|
+
const shouldClearContextFiles = contextFiles.hasChanges.value;
|
|
137
|
+
const shouldResetExternalSkills = externalSkills.hasChanges.value;
|
|
138
|
+
const onSaved = () => {
|
|
139
|
+
if (shouldUpdateKnowledgeSources)
|
|
140
|
+
setKnowledgeSources(pendingKnowledgeSources);
|
|
141
|
+
if (shouldClearContextFiles)
|
|
142
|
+
contextFiles.clearPendingFiles();
|
|
143
|
+
if (shouldResetExternalSkills)
|
|
144
|
+
externalSkills.initialize();
|
|
145
|
+
};
|
|
146
|
+
if (hasSettingsOverride.value) {
|
|
147
|
+
emit("save", { updates, onSaved });
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
await updateSettings(updates);
|
|
151
|
+
onSaved();
|
|
152
|
+
statusToast.update({
|
|
153
|
+
text: "Configura\xE7\xF5es salvas",
|
|
154
|
+
icon: "i-ph-check"
|
|
155
|
+
});
|
|
156
|
+
emit("update:open", false);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error("Failed to prepare settings update:", error);
|
|
159
|
+
statusToast.update({
|
|
160
|
+
text: "Erro ao salvar configura\xE7\xF5es",
|
|
161
|
+
icon: "i-ph-warning"
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function handleClose() {
|
|
166
|
+
if (isBusy.value)
|
|
167
|
+
return;
|
|
168
|
+
if (hasChanges.value)
|
|
169
|
+
showDiscardConfirm.value = true;
|
|
170
|
+
else
|
|
171
|
+
emit("update:open", false);
|
|
172
|
+
}
|
|
173
|
+
function confirmDiscard() {
|
|
174
|
+
showDiscardConfirm.value = false;
|
|
175
|
+
emit("update:open", false);
|
|
176
|
+
}
|
|
177
|
+
function cancelDiscard() {
|
|
178
|
+
showDiscardConfirm.value = false;
|
|
179
|
+
}
|
|
180
|
+
</script>
|
|
181
|
+
|
|
182
|
+
<template>
|
|
183
|
+
<TelaModal
|
|
184
|
+
:model-value="open"
|
|
185
|
+
modal-width="lg"
|
|
186
|
+
compact
|
|
187
|
+
hide-dividers
|
|
188
|
+
hide-header
|
|
189
|
+
class="!w-[min(1024px,95vw)] !max-w-[min(1024px,95vw)] p-0!"
|
|
190
|
+
@update:model-value="handleClose"
|
|
191
|
+
>
|
|
192
|
+
<div flex class="h-[min(722px,90vh)]" w-full>
|
|
193
|
+
<div w-256px bg-neutral-100 flex="~ col" overflow-hidden rounded-l-16px relative>
|
|
194
|
+
<p text-12px text-secondary px-16px pt-16px leading-16px style="color: #767E88;">
|
|
195
|
+
Configurações do Workspace
|
|
196
|
+
</p>
|
|
197
|
+
|
|
198
|
+
<div flex="~ col" gap-1px px-6px mt-24px>
|
|
199
|
+
<button
|
|
200
|
+
v-for="tab in settingsTabs"
|
|
201
|
+
:key="tab.value"
|
|
202
|
+
flex items-center gap-12px
|
|
203
|
+
px-12px py-7px
|
|
204
|
+
rounded-8px
|
|
205
|
+
cursor-pointer
|
|
206
|
+
transition
|
|
207
|
+
text-left
|
|
208
|
+
w-full
|
|
209
|
+
:class="[
|
|
210
|
+
activeTab === tab.value ? 'bg-black/4' : 'hover:bg-black/2'
|
|
211
|
+
]"
|
|
212
|
+
@click="activateTab(tab.value)"
|
|
213
|
+
>
|
|
214
|
+
<div
|
|
215
|
+
:class="tab.icon"
|
|
216
|
+
text-16px
|
|
217
|
+
:style="{ color: '#6B7280' }"
|
|
218
|
+
/>
|
|
219
|
+
<span
|
|
220
|
+
text-14px
|
|
221
|
+
tracking="-.15px"
|
|
222
|
+
leading-18px
|
|
223
|
+
font-460
|
|
224
|
+
:class="[
|
|
225
|
+
activeTab === tab.value ? 'text-primary' : 'text-secondary'
|
|
226
|
+
]"
|
|
227
|
+
>
|
|
228
|
+
{{ tab.label }}
|
|
229
|
+
</span>
|
|
230
|
+
</button>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<div flex-1 />
|
|
234
|
+
|
|
235
|
+
<div absolute bottom-0 left-0 w-full h-56px bg-gradient-to-t from-neutral-50 to-transparent pointer-events-none />
|
|
236
|
+
<div px-16px pb-16px relative z-10>
|
|
237
|
+
<button
|
|
238
|
+
p-6px rounded-full
|
|
239
|
+
bg-white b=".5px gray-200"
|
|
240
|
+
flex items-center justify-center
|
|
241
|
+
cursor-pointer
|
|
242
|
+
hover:bg-gray-50
|
|
243
|
+
transition
|
|
244
|
+
>
|
|
245
|
+
<div i-ph-question text-20px style="color: #767E88;" />
|
|
246
|
+
</button>
|
|
247
|
+
</div>
|
|
248
|
+
</div>
|
|
249
|
+
|
|
250
|
+
<div flex-1 flex="~ col" bg-white relative overflow-hidden rounded-r-16px>
|
|
251
|
+
<button
|
|
252
|
+
absolute top-12px right-12px
|
|
253
|
+
p-8px rounded-12px
|
|
254
|
+
hover:bg-gray-100
|
|
255
|
+
transition cursor-pointer
|
|
256
|
+
z-10
|
|
257
|
+
@click="handleClose"
|
|
258
|
+
>
|
|
259
|
+
<div i-ph-x text-24px text-primary />
|
|
260
|
+
</button>
|
|
261
|
+
|
|
262
|
+
<div flex-1 overflow-auto px-48px pt-32px pb-24px>
|
|
263
|
+
<div
|
|
264
|
+
v-if="loadingInitialSettings"
|
|
265
|
+
h-full min-h-360px flex="~ col" items-center justify-center gap-12px
|
|
266
|
+
>
|
|
267
|
+
<div i-ph-spinner animate-spin text-24px text-gray-500 />
|
|
268
|
+
<p text-14px text-gray-500>
|
|
269
|
+
Carregando configurações...
|
|
270
|
+
</p>
|
|
271
|
+
</div>
|
|
272
|
+
|
|
273
|
+
<ChatConfigurationPersonalizationTab
|
|
274
|
+
v-else-if="activeTab === 'personalization'"
|
|
275
|
+
v-model:system-message="personalization.localSystemMessage.value"
|
|
276
|
+
/>
|
|
277
|
+
|
|
278
|
+
<ChatConfigurationContextFilesTab
|
|
279
|
+
v-else-if="activeTab === 'context-files'"
|
|
280
|
+
:search-query="searchQuery"
|
|
281
|
+
:filtered-context-files="contextFiles.filteredContextFiles.value"
|
|
282
|
+
:filtered-pending-files="contextFiles.filteredPendingFiles.value"
|
|
283
|
+
:current-file-count="contextFiles.currentFileCount.value"
|
|
284
|
+
:max-files="contextFiles.maxFiles"
|
|
285
|
+
:get-file-type="contextFiles.getFileType"
|
|
286
|
+
@update:search-query="searchQuery = $event"
|
|
287
|
+
@handle-file-select="contextFiles.handleFileSelect"
|
|
288
|
+
@remove-pending-file="contextFiles.removePendingFile"
|
|
289
|
+
@remove-context-file="contextFiles.removeContextFile"
|
|
290
|
+
/>
|
|
291
|
+
|
|
292
|
+
<ChatConfigurationKnowledgeSourcesTab
|
|
293
|
+
v-else-if="activeTab === 'knowledge-sources'"
|
|
294
|
+
:search-query="searchQuery"
|
|
295
|
+
:workstations="workstations"
|
|
296
|
+
:loading-workstations="loadingWorkstations"
|
|
297
|
+
:filtered-workstations="knowledgeSources.filteredWorkstations.value"
|
|
298
|
+
:selected-ids="knowledgeSources.selectedKnowledgeSourceIds.value"
|
|
299
|
+
:get-project-name-for-workstation="knowledgeSources.getProjectNameForWorkstation"
|
|
300
|
+
@update:search-query="searchQuery = $event"
|
|
301
|
+
@toggle="knowledgeSources.toggleKnowledgeSource"
|
|
302
|
+
/>
|
|
303
|
+
|
|
304
|
+
<ChatConfigurationTelaToolsTab
|
|
305
|
+
v-else-if="activeTab === 'tela-tools'"
|
|
306
|
+
:search-query="searchQuery"
|
|
307
|
+
:canvas="canvas"
|
|
308
|
+
:filtered-canvas-tools="telaTools.filteredCanvasTools.value"
|
|
309
|
+
:selected-tool-ids="telaTools.selectedToolIds.value"
|
|
310
|
+
:all-tools-selected="telaTools.allToolsSelected.value"
|
|
311
|
+
:get-project-name="telaTools.getProjectName"
|
|
312
|
+
@update:search-query="searchQuery = $event"
|
|
313
|
+
@toggle-tool="telaTools.toggleCanvasTool"
|
|
314
|
+
@toggle-all="telaTools.toggleAllTools"
|
|
315
|
+
/>
|
|
316
|
+
|
|
317
|
+
<ChatConfigurationExternalSkillsTab
|
|
318
|
+
v-else-if="activeTab === 'external-skills'"
|
|
319
|
+
:search-query="searchQuery"
|
|
320
|
+
:displayed-skills="externalSkills.displayedSkills.value"
|
|
321
|
+
:filtered-skills="externalSkills.filteredSkills.value"
|
|
322
|
+
:has-changes="externalSkills.hasChanges.value"
|
|
323
|
+
:is-pending="externalSkills.isPending"
|
|
324
|
+
:skill-modal-open="externalSkills.skillModalOpen.value"
|
|
325
|
+
:skill-ref-input="externalSkills.skillRefInput.value"
|
|
326
|
+
:skill-error="externalSkills.skillError.value"
|
|
327
|
+
:discovering-skills="externalSkills.discoveringSkills.value"
|
|
328
|
+
:git-hub-button-text="gitHubButtonText"
|
|
329
|
+
@update:search-query="searchQuery = $event"
|
|
330
|
+
@update:skill-modal-open="externalSkills.skillModalOpen.value = $event"
|
|
331
|
+
@update:skill-ref-input="externalSkills.skillRefInput.value = $event"
|
|
332
|
+
@remove-skill="externalSkills.removeSkill"
|
|
333
|
+
@close-skill-modal="externalSkills.closeSkillModal"
|
|
334
|
+
@handle-add-skill-and-close="externalSkills.handleAddSkillAndClose"
|
|
335
|
+
@connect-git-hub="externalSkills.connectGitHub"
|
|
336
|
+
/>
|
|
337
|
+
|
|
338
|
+
<ChatConfigurationCredentialsTab
|
|
339
|
+
v-else-if="activeTab === 'credentials'"
|
|
340
|
+
:search-query="searchQuery"
|
|
341
|
+
@update:search-query="searchQuery = $event"
|
|
342
|
+
/>
|
|
343
|
+
</div>
|
|
344
|
+
|
|
345
|
+
<div flex-shrink-0 px-48px pb-48px flex justify-end gap-12px>
|
|
346
|
+
<TelaButton
|
|
347
|
+
size="lg"
|
|
348
|
+
:disabled="!hasChanges || isBusy"
|
|
349
|
+
@click="handleSave"
|
|
350
|
+
>
|
|
351
|
+
<span v-if="isBusy" flex items-center gap-6px>
|
|
352
|
+
<div i-ph-spinner animate-spin />
|
|
353
|
+
Salvando...
|
|
354
|
+
</span>
|
|
355
|
+
<span v-else>Salvar</span>
|
|
356
|
+
</TelaButton>
|
|
357
|
+
</div>
|
|
358
|
+
</div>
|
|
359
|
+
</div>
|
|
360
|
+
|
|
361
|
+
<TelaConfirmationModal
|
|
362
|
+
v-model:open="showDiscardConfirm"
|
|
363
|
+
title="Descartar alterações?"
|
|
364
|
+
variant="danger"
|
|
365
|
+
confirm-button-text="Descartar"
|
|
366
|
+
cancel-button-text="Continuar editando"
|
|
367
|
+
@confirm="confirmDiscard"
|
|
368
|
+
@cancel="cancelDiscard"
|
|
369
|
+
>
|
|
370
|
+
Você tem alterações não salvas. Deseja descartá-las?
|
|
371
|
+
</TelaConfirmationModal>
|
|
372
|
+
</TelaModal>
|
|
373
|
+
</template>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { DeepReadonly } from 'vue';
|
|
2
|
+
import type { WorkspaceSettings, WorkspaceSettingsUpdate } from '../../composables/useWorkspaceSettings.js';
|
|
3
|
+
export type ChatConfigurationTab = 'personalization' | 'context-files' | 'knowledge-sources' | 'tela-tools' | 'external-skills' | 'credentials';
|
|
4
|
+
export type ChatConfigurationSavePayload = {
|
|
5
|
+
updates: WorkspaceSettingsUpdate;
|
|
6
|
+
onSaved: () => void;
|
|
7
|
+
};
|
|
8
|
+
type __VLS_Props = {
|
|
9
|
+
open: boolean;
|
|
10
|
+
settings?: DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null;
|
|
11
|
+
initialTab?: ChatConfigurationTab;
|
|
12
|
+
saving?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
15
|
+
save: (payload: ChatConfigurationSavePayload) => any;
|
|
16
|
+
"update:open": (value: boolean) => any;
|
|
17
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
18
|
+
onSave?: ((payload: ChatConfigurationSavePayload) => any) | undefined;
|
|
19
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
20
|
+
}>, {
|
|
21
|
+
initialTab: ChatConfigurationTab;
|
|
22
|
+
saving: boolean;
|
|
23
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const _default: typeof __VLS_export;
|
|
25
|
+
export default _default;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import { provideEmbedConfig, useEmbedConfig } from "../../composables/useEmbedConfig";
|
|
2
3
|
import ChatEmbedInner from "./ChatEmbedInner.vue";
|
|
3
4
|
const props = defineProps({
|
|
4
5
|
workspaceId: { type: String, required: true },
|
|
@@ -10,7 +11,17 @@ const props = defineProps({
|
|
|
10
11
|
features: { type: Object, required: false }
|
|
11
12
|
});
|
|
12
13
|
defineEmits(["update:conversationId"]);
|
|
13
|
-
|
|
14
|
+
const parentEmbedConfig = useEmbedConfig();
|
|
15
|
+
if (import.meta.dev && parentEmbedConfig) {
|
|
16
|
+
watchEffect(() => {
|
|
17
|
+
const parentWorkspaceId = parentEmbedConfig.workspaceId.value.trim();
|
|
18
|
+
const propWorkspaceId = props.workspaceId.trim();
|
|
19
|
+
if (parentWorkspaceId && propWorkspaceId && parentWorkspaceId !== propWorkspaceId) {
|
|
20
|
+
console.warn(`[MeistrariChatEmbed] workspaceId prop (${propWorkspaceId}) differs from parent embed config (${parentWorkspaceId}); using prop value for this embed.`);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
provideEmbedConfig(props, { syncGlobal: !parentEmbedConfig });
|
|
14
25
|
</script>
|
|
15
26
|
|
|
16
27
|
<template>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { exportConversationToMarkdown } from "../../utils/export-conversation";
|
|
3
|
+
import { conversationListSkeletonRows } from "../../utils/conversation-list-skeleton";
|
|
3
4
|
import {
|
|
4
5
|
normalizeConversationId,
|
|
5
6
|
resolveChatFeatures,
|
|
@@ -18,9 +19,9 @@ const embedConfig = useEmbedConfig();
|
|
|
18
19
|
const { user: authUser } = useTelaApplicationAuth();
|
|
19
20
|
const { getMember } = useWorkspaceMembers();
|
|
20
21
|
const statusToast = useStatusToast();
|
|
21
|
-
const { conversations, fetchConversations, createConversation, deleteConversation, renameConversation, duplicateConversation } = useConversations();
|
|
22
|
+
const { conversations, loading: conversationsLoading, fetchConversations, createConversation, deleteConversation, renameConversation, duplicateConversation, updateConversationInList } = useConversations();
|
|
22
23
|
const { settings: workspaceSettingsState, fetchSettings } = useWorkspaceSettings();
|
|
23
|
-
const effectiveWorkspaceSettings = computed(() => embedConfig?.workspaceSettings.value
|
|
24
|
+
const effectiveWorkspaceSettings = computed(() => embedConfig?.workspaceSettings.value !== void 0 ? embedConfig.workspaceSettings.value : workspaceSettingsState.value);
|
|
24
25
|
const { closePanel: closeFilesPanel } = useConversationFilesPanel();
|
|
25
26
|
const activeConversationId = ref(
|
|
26
27
|
normalizeConversationId(props.conversationId) ?? normalizeConversationId(props.initialConversationId)
|
|
@@ -45,6 +46,7 @@ const {
|
|
|
45
46
|
animatedTitle,
|
|
46
47
|
hasPendingMessage,
|
|
47
48
|
loadConversation,
|
|
49
|
+
setConversation,
|
|
48
50
|
sendMessage,
|
|
49
51
|
retryMessage,
|
|
50
52
|
cancelConversation,
|
|
@@ -200,7 +202,7 @@ const displayTitle = computed(() => {
|
|
|
200
202
|
});
|
|
201
203
|
watch(
|
|
202
204
|
() => [currentConversation.value?.id ?? null, currentConversation.value?.title ?? null],
|
|
203
|
-
([conversationId, conversationTitle], [previousConversationId]) => {
|
|
205
|
+
([conversationId, conversationTitle], [previousConversationId, previousTitle]) => {
|
|
204
206
|
if (conversationId !== previousConversationId) {
|
|
205
207
|
optimisticTitle.value = null;
|
|
206
208
|
return;
|
|
@@ -208,6 +210,9 @@ watch(
|
|
|
208
210
|
if (optimisticTitle.value !== null && conversationTitle === optimisticTitle.value) {
|
|
209
211
|
optimisticTitle.value = null;
|
|
210
212
|
}
|
|
213
|
+
if (conversationTitle && conversationTitle !== previousTitle && currentConversation.value) {
|
|
214
|
+
updateConversationInList(currentConversation.value);
|
|
215
|
+
}
|
|
211
216
|
}
|
|
212
217
|
);
|
|
213
218
|
const currentUser = computed(() => props.user ?? authUser.value ?? null);
|
|
@@ -218,22 +223,23 @@ const conversationCreator = computed(
|
|
|
218
223
|
})
|
|
219
224
|
);
|
|
220
225
|
async function handleSend(content, files, model) {
|
|
226
|
+
let createdConversationId = null;
|
|
221
227
|
if (!activeConversationId.value || !currentConversation.value) {
|
|
222
228
|
const conversation = await createConversation({
|
|
223
229
|
model: model ?? selectedModel.value
|
|
224
230
|
});
|
|
225
231
|
if (!conversation)
|
|
226
232
|
return;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
if (!currentConversation.value) {
|
|
230
|
-
statusToast.update({ text: "Erro ao carregar conversa", icon: "i-ph-warning" });
|
|
231
|
-
return;
|
|
232
|
-
}
|
|
233
|
+
setConversation(conversation);
|
|
234
|
+
createdConversationId = conversation.id;
|
|
233
235
|
}
|
|
234
236
|
if (!currentConversation.value)
|
|
235
237
|
return;
|
|
236
|
-
|
|
238
|
+
const sendPromise = sendMessage(content, files.length > 0 ? files : void 0, model);
|
|
239
|
+
if (createdConversationId) {
|
|
240
|
+
updateConversationId(createdConversationId);
|
|
241
|
+
}
|
|
242
|
+
await sendPromise;
|
|
237
243
|
}
|
|
238
244
|
async function handleRetry(messageId) {
|
|
239
245
|
await retryMessage(messageId);
|
|
@@ -295,8 +301,8 @@ async function handleDuplicate() {
|
|
|
295
301
|
return;
|
|
296
302
|
const duplicated = await duplicateConversation(currentConversation.value.id);
|
|
297
303
|
if (duplicated) {
|
|
304
|
+
setConversation(duplicated);
|
|
298
305
|
updateConversationId(duplicated.id);
|
|
299
|
-
await ensureConversationLoaded(duplicated.id);
|
|
300
306
|
}
|
|
301
307
|
}
|
|
302
308
|
async function handleExport() {
|
|
@@ -322,9 +328,6 @@ async function handleDelete() {
|
|
|
322
328
|
await handleNewConversation();
|
|
323
329
|
}
|
|
324
330
|
}
|
|
325
|
-
onBeforeUnmount(() => {
|
|
326
|
-
clearConversation();
|
|
327
|
-
});
|
|
328
331
|
</script>
|
|
329
332
|
|
|
330
333
|
<template>
|
|
@@ -351,7 +354,16 @@ onBeforeUnmount(() => {
|
|
|
351
354
|
</div>
|
|
352
355
|
|
|
353
356
|
<div flex-1 overflow-y-auto px-4px>
|
|
354
|
-
<div v-if="visibleConversations.length === 0"
|
|
357
|
+
<div v-if="conversationsLoading && visibleConversations.length === 0" flex="~ col" gap-1px px-8px py-8px>
|
|
358
|
+
<div
|
|
359
|
+
v-for="row in conversationListSkeletonRows"
|
|
360
|
+
:key="row.id"
|
|
361
|
+
flex items-center h-32px px-8px rounded-8px
|
|
362
|
+
>
|
|
363
|
+
<TelaSkeleton rounded-6px bg-neutral-200 :style="{ width: row.width, height: '13px' }" />
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
<div v-else-if="visibleConversations.length === 0" p-16px text-center>
|
|
355
367
|
<p text-14px text-neutral-400>
|
|
356
368
|
Nenhuma conversa ainda
|
|
357
369
|
</p>
|
|
@@ -449,7 +461,10 @@ onBeforeUnmount(() => {
|
|
|
449
461
|
</template>
|
|
450
462
|
|
|
451
463
|
<template v-else-if="loading">
|
|
452
|
-
<
|
|
464
|
+
<ChatMessageList
|
|
465
|
+
:messages="[]"
|
|
466
|
+
loading
|
|
467
|
+
/>
|
|
453
468
|
<ChatMessageInput
|
|
454
469
|
v-model:model="selectedModel"
|
|
455
470
|
:disabled="true"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ContextFile } from '../../../server/db/schema.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
searchQuery: string;
|
|
4
|
+
filteredContextFiles: readonly ContextFile[];
|
|
5
|
+
filteredPendingFiles: readonly File[];
|
|
6
|
+
currentFileCount: number;
|
|
7
|
+
maxFiles: number;
|
|
8
|
+
getFileType: (fileName: string) => string;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
11
|
+
handleFileSelect: (event: Event) => any;
|
|
12
|
+
removeContextFile: (url: string) => any;
|
|
13
|
+
removePendingFile: (file: File) => any;
|
|
14
|
+
"update:searchQuery": (value: string) => any;
|
|
15
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
16
|
+
onHandleFileSelect?: ((event: Event) => any) | undefined;
|
|
17
|
+
onRemoveContextFile?: ((url: string) => any) | undefined;
|
|
18
|
+
onRemovePendingFile?: ((file: File) => any) | undefined;
|
|
19
|
+
"onUpdate:searchQuery"?: ((value: string) => any) | undefined;
|
|
20
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
21
|
+
declare const _default: typeof __VLS_export;
|
|
22
|
+
export default _default;
|