@meistrari/chat-nuxt 1.1.3 → 1.2.1
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 +70 -4
- package/dist/module.d.mts +5 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +74 -27
- 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 +6 -3
- package/dist/runtime/composables/useConversations.js +114 -12
- 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/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 +11 -12
- 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 +35 -19
- 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/conversations/[id]/duplicate.post.js +45 -12
- 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 +23 -27
- package/dist/runtime/composables/PageNavigation.d.ts +0 -13
- package/dist/runtime/composables/PageNavigation.js +0 -18
- /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
- /package/dist/runtime/public/{github.svg → assets/github.svg} +0 -0
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
import * as Sentry from "@sentry/nuxt";
|
|
2
|
+
function sortConversationsByUpdatedAt(conversations) {
|
|
3
|
+
return [...conversations].sort(
|
|
4
|
+
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
5
|
+
);
|
|
6
|
+
}
|
|
7
|
+
export function mergeFetchedConversations(fetchedConversations, localConversations, deletedConversationIds = [], locallyMutatedConversationIds = []) {
|
|
8
|
+
const deletedIds = new Set(deletedConversationIds);
|
|
9
|
+
const locallyMutatedIds = new Set(locallyMutatedConversationIds);
|
|
10
|
+
const mergedById = /* @__PURE__ */ new Map();
|
|
11
|
+
for (const conversation of fetchedConversations) {
|
|
12
|
+
if (!deletedIds.has(conversation.id)) {
|
|
13
|
+
mergedById.set(conversation.id, conversation);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
for (const conversation of localConversations) {
|
|
17
|
+
if (!deletedIds.has(conversation.id)) {
|
|
18
|
+
if (!mergedById.has(conversation.id) || locallyMutatedIds.has(conversation.id)) {
|
|
19
|
+
mergedById.set(conversation.id, conversation);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return sortConversationsByUpdatedAt([...mergedById.values()]);
|
|
24
|
+
}
|
|
2
25
|
export function useConversations() {
|
|
3
26
|
const chatApi = useChatApi();
|
|
4
27
|
const embedConfig = useEmbedConfig();
|
|
28
|
+
const { activeOrganization } = useTelaApplicationAuth();
|
|
5
29
|
const conversationBuckets = useState("conversations", () => ({}));
|
|
6
30
|
const loadingBuckets = useState("conversations-loading", () => ({}));
|
|
7
31
|
const errorBuckets = useState("conversations-error", () => ({}));
|
|
8
|
-
const
|
|
32
|
+
const fetchedBuckets = useState("conversations-fetched", () => ({}));
|
|
33
|
+
const mutationVersionBuckets = useState("conversations-mutation-version", () => ({}));
|
|
34
|
+
const deletedIdBuckets = useState("conversations-deleted-ids", () => ({}));
|
|
35
|
+
const mutatedIdBuckets = useState("conversations-mutated-ids", () => ({}));
|
|
36
|
+
const workspaceScope = computed(() => embedConfig?.workspaceId.value.trim() || activeOrganization.value?.id?.trim() || "default");
|
|
9
37
|
const conversations = computed({
|
|
10
38
|
get: () => conversationBuckets.value[workspaceScope.value] ?? [],
|
|
11
39
|
set: (value) => {
|
|
@@ -15,6 +43,33 @@ export function useConversations() {
|
|
|
15
43
|
};
|
|
16
44
|
}
|
|
17
45
|
});
|
|
46
|
+
const mutationVersion = computed({
|
|
47
|
+
get: () => mutationVersionBuckets.value[workspaceScope.value] ?? 0,
|
|
48
|
+
set: (value) => {
|
|
49
|
+
mutationVersionBuckets.value = {
|
|
50
|
+
...mutationVersionBuckets.value,
|
|
51
|
+
[workspaceScope.value]: value
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
});
|
|
55
|
+
const deletedConversationIds = computed({
|
|
56
|
+
get: () => deletedIdBuckets.value[workspaceScope.value] ?? [],
|
|
57
|
+
set: (value) => {
|
|
58
|
+
deletedIdBuckets.value = {
|
|
59
|
+
...deletedIdBuckets.value,
|
|
60
|
+
[workspaceScope.value]: value
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
const mutatedConversationIds = computed({
|
|
65
|
+
get: () => mutatedIdBuckets.value[workspaceScope.value] ?? [],
|
|
66
|
+
set: (value) => {
|
|
67
|
+
mutatedIdBuckets.value = {
|
|
68
|
+
...mutatedIdBuckets.value,
|
|
69
|
+
[workspaceScope.value]: value
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
});
|
|
18
73
|
const loading = computed({
|
|
19
74
|
get: () => loadingBuckets.value[workspaceScope.value] ?? false,
|
|
20
75
|
set: (value) => {
|
|
@@ -33,20 +88,69 @@ export function useConversations() {
|
|
|
33
88
|
};
|
|
34
89
|
}
|
|
35
90
|
});
|
|
91
|
+
const hasFetched = computed({
|
|
92
|
+
get: () => fetchedBuckets.value[workspaceScope.value] ?? false,
|
|
93
|
+
set: (value) => {
|
|
94
|
+
fetchedBuckets.value = {
|
|
95
|
+
...fetchedBuckets.value,
|
|
96
|
+
[workspaceScope.value]: value
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
function markMutated(id) {
|
|
101
|
+
mutationVersion.value = mutationVersion.value + 1;
|
|
102
|
+
if (id) {
|
|
103
|
+
mutatedConversationIds.value = [.../* @__PURE__ */ new Set([...mutatedConversationIds.value, id])];
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
function commitConversations(nextConversations, mutatedId) {
|
|
107
|
+
conversations.value = sortConversationsByUpdatedAt(nextConversations);
|
|
108
|
+
markMutated(mutatedId);
|
|
109
|
+
}
|
|
110
|
+
function addDeletedConversationId(id) {
|
|
111
|
+
deletedConversationIds.value = [.../* @__PURE__ */ new Set([...deletedConversationIds.value, id])];
|
|
112
|
+
markMutated();
|
|
113
|
+
}
|
|
114
|
+
function removeDeletedConversationId(id) {
|
|
115
|
+
deletedConversationIds.value = deletedConversationIds.value.filter((deletedId) => deletedId !== id);
|
|
116
|
+
markMutated();
|
|
117
|
+
}
|
|
118
|
+
function pruneDeletedConversationIds(serverConversations) {
|
|
119
|
+
const returnedIds = new Set(serverConversations.map((conversation) => conversation.id));
|
|
120
|
+
deletedConversationIds.value = deletedConversationIds.value.filter((id) => returnedIds.has(id));
|
|
121
|
+
}
|
|
36
122
|
function cloneAppliedSettingsSnapshot(snapshot) {
|
|
37
123
|
if (!snapshot)
|
|
38
124
|
return null;
|
|
39
125
|
return JSON.parse(JSON.stringify(snapshot));
|
|
40
126
|
}
|
|
41
|
-
const fetchConversations = async () => {
|
|
127
|
+
const fetchConversations = async (options = {}) => {
|
|
128
|
+
if (loading.value || hasFetched.value && !options.force) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
42
131
|
loading.value = true;
|
|
43
132
|
error.value = null;
|
|
133
|
+
const mutationVersionAtStart = mutationVersion.value;
|
|
44
134
|
try {
|
|
45
135
|
const data = await $fetch(
|
|
46
136
|
chatApi.path("/conversations"),
|
|
47
137
|
chatApi.withChatHeaders()
|
|
48
138
|
);
|
|
49
|
-
|
|
139
|
+
const visibleData = data.filter((conversation) => !deletedConversationIds.value.includes(conversation.id));
|
|
140
|
+
if (mutationVersion.value === mutationVersionAtStart) {
|
|
141
|
+
conversations.value = sortConversationsByUpdatedAt(visibleData);
|
|
142
|
+
mutatedConversationIds.value = [];
|
|
143
|
+
} else {
|
|
144
|
+
conversations.value = mergeFetchedConversations(
|
|
145
|
+
visibleData,
|
|
146
|
+
conversations.value,
|
|
147
|
+
deletedConversationIds.value,
|
|
148
|
+
mutatedConversationIds.value
|
|
149
|
+
);
|
|
150
|
+
mutatedConversationIds.value = [];
|
|
151
|
+
}
|
|
152
|
+
pruneDeletedConversationIds(data);
|
|
153
|
+
hasFetched.value = true;
|
|
50
154
|
} catch (err) {
|
|
51
155
|
const message = err instanceof Error ? err.message : "Erro ao carregar conversas";
|
|
52
156
|
error.value = message;
|
|
@@ -65,7 +169,7 @@ export function useConversations() {
|
|
|
65
169
|
body: options?.model ? { model: options.model } : void 0
|
|
66
170
|
})
|
|
67
171
|
);
|
|
68
|
-
|
|
172
|
+
commitConversations([conversation, ...conversations.value], conversation.id);
|
|
69
173
|
return conversation;
|
|
70
174
|
} catch (err) {
|
|
71
175
|
const message = err instanceof Error ? err.message : "Erro ao criar conversa";
|
|
@@ -77,7 +181,8 @@ export function useConversations() {
|
|
|
77
181
|
error.value = null;
|
|
78
182
|
const statusToast = useStatusToast();
|
|
79
183
|
const deletedConversation = conversations.value.find((c) => c.id === id);
|
|
80
|
-
|
|
184
|
+
addDeletedConversationId(id);
|
|
185
|
+
commitConversations(conversations.value.filter((c) => c.id !== id), id);
|
|
81
186
|
try {
|
|
82
187
|
await $fetch(
|
|
83
188
|
chatApi.path(`/conversations/${id}`),
|
|
@@ -91,10 +196,9 @@ export function useConversations() {
|
|
|
91
196
|
});
|
|
92
197
|
return true;
|
|
93
198
|
} catch (err) {
|
|
199
|
+
removeDeletedConversationId(id);
|
|
94
200
|
if (deletedConversation) {
|
|
95
|
-
|
|
96
|
-
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
97
|
-
);
|
|
201
|
+
commitConversations([...conversations.value, deletedConversation], deletedConversation.id);
|
|
98
202
|
}
|
|
99
203
|
const message = err instanceof Error ? err.message : "Erro ao deletar conversa";
|
|
100
204
|
error.value = message;
|
|
@@ -122,9 +226,7 @@ export function useConversations() {
|
|
|
122
226
|
createdAt: updated.createdAt,
|
|
123
227
|
updatedAt: updated.updatedAt
|
|
124
228
|
};
|
|
125
|
-
|
|
126
|
-
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
127
|
-
);
|
|
229
|
+
commitConversations(nextConversations, updated.id);
|
|
128
230
|
}
|
|
129
231
|
};
|
|
130
232
|
const renameConversation = async (id, title) => {
|
|
@@ -161,7 +263,7 @@ export function useConversations() {
|
|
|
161
263
|
method: "POST"
|
|
162
264
|
})
|
|
163
265
|
);
|
|
164
|
-
|
|
266
|
+
commitConversations([duplicated, ...conversations.value], duplicated.id);
|
|
165
267
|
statusToast.update({
|
|
166
268
|
text: "Conversa duplicada",
|
|
167
269
|
icon: "i-ph-check"
|
|
@@ -1,13 +1,18 @@
|
|
|
1
|
-
import type { DeepReadonly, Ref } from 'vue';
|
|
1
|
+
import type { DeepReadonly, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
2
|
import type { WorkspaceSettings } from './useWorkspaceSettings.js';
|
|
3
3
|
export type EmbedConfig = {
|
|
4
4
|
workspaceId: Ref<string>;
|
|
5
5
|
workspaceSettings: Ref<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
6
6
|
hideSidebar: Ref<boolean>;
|
|
7
7
|
};
|
|
8
|
-
|
|
9
|
-
workspaceId: string
|
|
10
|
-
workspaceSettings?: DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null
|
|
11
|
-
hideSidebar?: boolean
|
|
12
|
-
}
|
|
8
|
+
type EmbedConfigInput = {
|
|
9
|
+
workspaceId: MaybeRefOrGetter<string>;
|
|
10
|
+
workspaceSettings?: MaybeRefOrGetter<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
11
|
+
hideSidebar?: MaybeRefOrGetter<boolean | undefined>;
|
|
12
|
+
};
|
|
13
|
+
type ProvideEmbedConfigOptions = {
|
|
14
|
+
syncGlobal?: boolean;
|
|
15
|
+
};
|
|
16
|
+
export declare function provideEmbedConfig(input: EmbedConfigInput, options?: ProvideEmbedConfigOptions): void;
|
|
13
17
|
export declare function useEmbedConfig(): EmbedConfig | null;
|
|
18
|
+
export {};
|
|
@@ -1,11 +1,39 @@
|
|
|
1
1
|
const EMBED_CONFIG_KEY = "embed-config";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
2
|
+
function useGlobalEmbedConfigState() {
|
|
3
|
+
return {
|
|
4
|
+
provided: useState("chat-embed-config-provided", () => false),
|
|
5
|
+
workspaceId: useState("chat-embed-config-workspace-id", () => ""),
|
|
6
|
+
workspaceSettings: useState("chat-embed-config-workspace-settings", () => void 0),
|
|
7
|
+
hideSidebar: useState("chat-embed-config-hide-sidebar", () => void 0)
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function provideEmbedConfig(input, options = {}) {
|
|
11
|
+
const config = {
|
|
12
|
+
workspaceId: computed(() => toValue(input.workspaceId)),
|
|
13
|
+
workspaceSettings: computed(() => toValue(input.workspaceSettings)),
|
|
14
|
+
hideSidebar: computed(() => toValue(input.hideSidebar) ?? true)
|
|
15
|
+
};
|
|
16
|
+
const globalConfig = useGlobalEmbedConfigState();
|
|
17
|
+
if (options.syncGlobal ?? true) {
|
|
18
|
+
watchEffect(() => {
|
|
19
|
+
globalConfig.provided.value = true;
|
|
20
|
+
globalConfig.workspaceId.value = config.workspaceId.value;
|
|
21
|
+
globalConfig.workspaceSettings.value = config.workspaceSettings.value;
|
|
22
|
+
globalConfig.hideSidebar.value = config.hideSidebar.value;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
provide(EMBED_CONFIG_KEY, config);
|
|
8
26
|
}
|
|
9
27
|
export function useEmbedConfig() {
|
|
10
|
-
|
|
28
|
+
const injectedConfig = inject(EMBED_CONFIG_KEY, null);
|
|
29
|
+
if (injectedConfig)
|
|
30
|
+
return injectedConfig;
|
|
31
|
+
const globalConfig = useGlobalEmbedConfigState();
|
|
32
|
+
if (!globalConfig.provided.value)
|
|
33
|
+
return null;
|
|
34
|
+
return {
|
|
35
|
+
workspaceId: computed(() => globalConfig.workspaceId.value),
|
|
36
|
+
workspaceSettings: computed(() => globalConfig.workspaceSettings.value),
|
|
37
|
+
hideSidebar: computed(() => globalConfig.hideSidebar.value ?? true)
|
|
38
|
+
};
|
|
11
39
|
}
|
|
@@ -2,6 +2,8 @@ export function useIDB(options) {
|
|
|
2
2
|
const { dbName = "tela", storeName, version } = options;
|
|
3
3
|
let dbInstance = null;
|
|
4
4
|
async function setup() {
|
|
5
|
+
if (!import.meta.client)
|
|
6
|
+
return null;
|
|
5
7
|
if (dbInstance)
|
|
6
8
|
return dbInstance;
|
|
7
9
|
return new Promise((resolve, reject) => {
|
|
@@ -36,6 +38,8 @@ export function useIDB(options) {
|
|
|
36
38
|
}
|
|
37
39
|
async function withStore(mode, callback) {
|
|
38
40
|
const db = await setup();
|
|
41
|
+
if (!db)
|
|
42
|
+
return null;
|
|
39
43
|
return new Promise((resolve, reject) => {
|
|
40
44
|
const transaction = db.transaction(storeName, mode);
|
|
41
45
|
const store = transaction.objectStore(storeName);
|