@meistrari/chat-nuxt 1.2.0 → 1.2.2
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/dist/module.json +1 -1
- package/dist/module.mjs +17 -9
- package/dist/runtime/composables/useChat.js +2 -1
- package/dist/runtime/composables/useConversationFiles.d.ts +3 -0
- package/dist/runtime/composables/useConversationFiles.js +31 -17
- package/dist/runtime/composables/useConversations.d.ts +3 -1
- package/dist/runtime/composables/useConversations.js +15 -1
- package/dist/runtime/composables/useKnowledgeSources.js +1 -1
- package/dist/runtime/composables/useMediaCache.js +12 -7
- package/dist/runtime/composables/useWorkspaceSettings.js +0 -4
- package/dist/runtime/embed/components/ChatEmbedInner.vue +4 -3
- package/dist/runtime/embed/components/configuration/ChatConfigurationExternalSkillsTab.vue +1 -1
- package/package.json +1 -1
- /package/dist/runtime/public/{github.svg → assets/github.svg} +0 -0
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -220,10 +220,12 @@ const module$1 = defineNuxtModule({
|
|
|
220
220
|
}
|
|
221
221
|
ensureIconifyPackages(nuxt.options.rootDir);
|
|
222
222
|
const resolver = createResolver(import.meta.url);
|
|
223
|
-
const
|
|
223
|
+
const builtRuntimeDir = resolver.resolve("./runtime");
|
|
224
|
+
const sourceRuntimeDir = resolver.resolve("../src/runtime");
|
|
225
|
+
const runtimeDir = nuxt.options.dev && existsSync(sourceRuntimeDir) ? sourceRuntimeDir : builtRuntimeDir;
|
|
224
226
|
const workspaceSettingsResolverEntry = resolveWorkspaceSettingsResolverEntry(
|
|
225
227
|
nuxt.options.srcDir,
|
|
226
|
-
|
|
228
|
+
join(runtimeDir, "internal/workspace-settings-resolver.stub")
|
|
227
229
|
);
|
|
228
230
|
const telaBuildPath = resolveTelaBuildLayer();
|
|
229
231
|
const runtimeAliases = resolveRuntimeAliases(telaBuildPath);
|
|
@@ -258,18 +260,18 @@ const module$1 = defineNuxtModule({
|
|
|
258
260
|
rc.public = rc.public || {};
|
|
259
261
|
rc.public.agentApiUrl = rc.public.agentApiUrl || process.env.AGENT_API_URL || "";
|
|
260
262
|
validateRuntimeConfig(rc, options.validateConfig ?? false);
|
|
261
|
-
addImportsDir(
|
|
262
|
-
addImportsDir(
|
|
263
|
+
addImportsDir(join(runtimeDir, "composables"));
|
|
264
|
+
addImportsDir(join(runtimeDir, "utils"));
|
|
263
265
|
addComponent({
|
|
264
266
|
name: "MeistrariChatEmbed",
|
|
265
|
-
filePath:
|
|
267
|
+
filePath: join(runtimeDir, "components/MeistrariChatEmbed.vue"),
|
|
266
268
|
priority: 1e3
|
|
267
269
|
});
|
|
268
270
|
addComponentsDir({
|
|
269
|
-
path:
|
|
271
|
+
path: join(runtimeDir, "components")
|
|
270
272
|
});
|
|
271
273
|
addComponentsDir({
|
|
272
|
-
path:
|
|
274
|
+
path: join(runtimeDir, "embed/components"),
|
|
273
275
|
pathPrefix: false
|
|
274
276
|
});
|
|
275
277
|
nuxt.hook("vite:extendConfig", (config, { isServer }) => {
|
|
@@ -310,8 +312,9 @@ export default globalThis.ELK;
|
|
|
310
312
|
}
|
|
311
313
|
});
|
|
312
314
|
});
|
|
313
|
-
const serverDir =
|
|
314
|
-
const
|
|
315
|
+
const serverDir = join(runtimeDir, "server");
|
|
316
|
+
const publicAssetsDir = join(runtimeDir, "public/assets");
|
|
317
|
+
const publicFilesDir = join(runtimeDir, "public/files");
|
|
315
318
|
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
316
319
|
nitroConfig.scanDirs = nitroConfig.scanDirs || [];
|
|
317
320
|
nitroConfig.scanDirs.push(serverDir);
|
|
@@ -321,6 +324,11 @@ export default globalThis.ELK;
|
|
|
321
324
|
"#chat-workspace-settings-resolver": workspaceSettingsResolverEntry
|
|
322
325
|
};
|
|
323
326
|
nitroConfig.publicAssets = nitroConfig.publicAssets || [];
|
|
327
|
+
nitroConfig.publicAssets.push({
|
|
328
|
+
dir: publicAssetsDir,
|
|
329
|
+
baseURL: "/chat-assets",
|
|
330
|
+
maxAge: 60 * 60 * 24 * 7
|
|
331
|
+
});
|
|
324
332
|
nitroConfig.publicAssets.push({
|
|
325
333
|
dir: publicFilesDir,
|
|
326
334
|
baseURL: "/chat-files",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as Sentry from "@sentry/nuxt";
|
|
2
2
|
import { exportConversationToMarkdown } from "../utils/export-conversation.js";
|
|
3
|
-
import {
|
|
3
|
+
import { useConversationFileActions } from "./useConversationFiles.js";
|
|
4
4
|
function getStepKey(step) {
|
|
5
5
|
if (typeof step === "string") {
|
|
6
6
|
return `text:${step.slice(0, 100)}`;
|
|
@@ -146,6 +146,7 @@ export function useChat() {
|
|
|
146
146
|
const chatApi = useChatApi();
|
|
147
147
|
const embedConfig = useEmbedConfig();
|
|
148
148
|
const { user: authUser, activeOrganization } = useTelaApplicationAuth();
|
|
149
|
+
const { addFilesToConversation } = useConversationFileActions();
|
|
149
150
|
const chatScope = computed(() => embedConfig?.workspaceId.value.trim() || activeOrganization.value?.id?.trim() || "default");
|
|
150
151
|
const currentConversationBuckets = useState("chat-current-conversation", () => ({}));
|
|
151
152
|
const messageBuckets = useState("chat-messages", () => ({}));
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import type { MessageFile, MessageRole } from '../types/chat.js';
|
|
2
2
|
export declare function addFilesToConversation(conversationId: string, newFiles: MessageFile[], messageId: string, messageRole: MessageRole): void;
|
|
3
|
+
export declare function useConversationFileActions(): {
|
|
4
|
+
addFilesToConversation: (conversationId: string, newFiles: MessageFile[], messageId: string, messageRole: MessageRole) => void;
|
|
5
|
+
};
|
|
3
6
|
export declare function useConversationFiles(conversationId: Ref<string | null | undefined>): {
|
|
4
7
|
files: any;
|
|
5
8
|
total: any;
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import { generateFileId } from "../utils/file.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
function useConversationFilesState() {
|
|
3
|
+
return {
|
|
4
|
+
files: useState("conversationFiles", () => ({})),
|
|
5
|
+
loading: useState("conversationFilesLoading", () => ({})),
|
|
6
|
+
error: useState("conversationFilesError", () => ({}))
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
function addFilesToConversationState(state, conversationId, newFiles, messageId, messageRole) {
|
|
10
|
+
const current = state.files.value[conversationId] ?? [];
|
|
7
11
|
const filesToAdd = newFiles.filter((f) => !current.some((existing) => existing.url === f.url)).map((f) => ({
|
|
8
12
|
id: generateFileId(f.url),
|
|
9
13
|
url: f.url,
|
|
@@ -16,26 +20,36 @@ export function addFilesToConversation(conversationId, newFiles, messageId, mess
|
|
|
16
20
|
size: f.size
|
|
17
21
|
}));
|
|
18
22
|
if (filesToAdd.length > 0) {
|
|
19
|
-
|
|
20
|
-
...
|
|
23
|
+
state.files.value = {
|
|
24
|
+
...state.files.value,
|
|
21
25
|
[conversationId]: [...filesToAdd, ...current]
|
|
22
26
|
};
|
|
23
27
|
}
|
|
24
28
|
}
|
|
29
|
+
export function addFilesToConversation(conversationId, newFiles, messageId, messageRole) {
|
|
30
|
+
addFilesToConversationState(useConversationFilesState(), conversationId, newFiles, messageId, messageRole);
|
|
31
|
+
}
|
|
32
|
+
export function useConversationFileActions() {
|
|
33
|
+
const state = useConversationFilesState();
|
|
34
|
+
return {
|
|
35
|
+
addFilesToConversation: (conversationId, newFiles, messageId, messageRole) => addFilesToConversationState(state, conversationId, newFiles, messageId, messageRole)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
25
38
|
export function useConversationFiles(conversationId) {
|
|
26
39
|
const chatApi = useChatApi();
|
|
40
|
+
const state = useConversationFilesState();
|
|
27
41
|
const files = computed(() => {
|
|
28
42
|
const id = conversationId.value;
|
|
29
|
-
return id ?
|
|
43
|
+
return id ? state.files.value[id] ?? [] : [];
|
|
30
44
|
});
|
|
31
45
|
const total = computed(() => files.value.length);
|
|
32
46
|
const loading = computed(() => {
|
|
33
47
|
const id = conversationId.value;
|
|
34
|
-
return id ?
|
|
48
|
+
return id ? state.loading.value[id] ?? false : false;
|
|
35
49
|
});
|
|
36
50
|
const error = computed(() => {
|
|
37
51
|
const id = conversationId.value;
|
|
38
|
-
return id ?
|
|
52
|
+
return id ? state.error.value[id] ?? null : null;
|
|
39
53
|
});
|
|
40
54
|
let currentFetchId = 0;
|
|
41
55
|
async function fetchFiles() {
|
|
@@ -43,27 +57,27 @@ export function useConversationFiles(conversationId) {
|
|
|
43
57
|
if (!id)
|
|
44
58
|
return;
|
|
45
59
|
const fetchId = ++currentFetchId;
|
|
46
|
-
|
|
47
|
-
|
|
60
|
+
state.loading.value = { ...state.loading.value, [id]: true };
|
|
61
|
+
state.error.value = { ...state.error.value, [id]: null };
|
|
48
62
|
try {
|
|
49
63
|
const response = await $fetch(
|
|
50
64
|
chatApi.path(`/conversations/${id}/files`),
|
|
51
65
|
chatApi.withChatHeaders()
|
|
52
66
|
);
|
|
53
67
|
if (fetchId === currentFetchId) {
|
|
54
|
-
|
|
68
|
+
state.files.value = { ...state.files.value, [id]: response.files };
|
|
55
69
|
}
|
|
56
70
|
} catch (err) {
|
|
57
71
|
if (fetchId === currentFetchId) {
|
|
58
|
-
|
|
59
|
-
...
|
|
72
|
+
state.error.value = {
|
|
73
|
+
...state.error.value,
|
|
60
74
|
[id]: err instanceof Error ? err.message : "Falha ao buscar arquivos"
|
|
61
75
|
};
|
|
62
|
-
|
|
76
|
+
state.files.value = { ...state.files.value, [id]: [] };
|
|
63
77
|
}
|
|
64
78
|
} finally {
|
|
65
79
|
if (fetchId === currentFetchId) {
|
|
66
|
-
|
|
80
|
+
state.loading.value = { ...state.loading.value, [id]: false };
|
|
67
81
|
}
|
|
68
82
|
}
|
|
69
83
|
}
|
|
@@ -5,7 +5,9 @@ export declare function useConversations(): {
|
|
|
5
5
|
conversations: any;
|
|
6
6
|
loading: any;
|
|
7
7
|
error: any;
|
|
8
|
-
fetchConversations: (
|
|
8
|
+
fetchConversations: (options?: {
|
|
9
|
+
force?: boolean;
|
|
10
|
+
}) => Promise<void>;
|
|
9
11
|
createConversation: (options?: {
|
|
10
12
|
model?: ModelOption | null;
|
|
11
13
|
}) => Promise<Conversation | null>;
|
|
@@ -29,6 +29,7 @@ export function useConversations() {
|
|
|
29
29
|
const conversationBuckets = useState("conversations", () => ({}));
|
|
30
30
|
const loadingBuckets = useState("conversations-loading", () => ({}));
|
|
31
31
|
const errorBuckets = useState("conversations-error", () => ({}));
|
|
32
|
+
const fetchedBuckets = useState("conversations-fetched", () => ({}));
|
|
32
33
|
const mutationVersionBuckets = useState("conversations-mutation-version", () => ({}));
|
|
33
34
|
const deletedIdBuckets = useState("conversations-deleted-ids", () => ({}));
|
|
34
35
|
const mutatedIdBuckets = useState("conversations-mutated-ids", () => ({}));
|
|
@@ -87,6 +88,15 @@ export function useConversations() {
|
|
|
87
88
|
};
|
|
88
89
|
}
|
|
89
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
|
+
});
|
|
90
100
|
function markMutated(id) {
|
|
91
101
|
mutationVersion.value = mutationVersion.value + 1;
|
|
92
102
|
if (id) {
|
|
@@ -114,7 +124,10 @@ export function useConversations() {
|
|
|
114
124
|
return null;
|
|
115
125
|
return JSON.parse(JSON.stringify(snapshot));
|
|
116
126
|
}
|
|
117
|
-
const fetchConversations = async () => {
|
|
127
|
+
const fetchConversations = async (options = {}) => {
|
|
128
|
+
if (loading.value || hasFetched.value && !options.force) {
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
118
131
|
loading.value = true;
|
|
119
132
|
error.value = null;
|
|
120
133
|
const mutationVersionAtStart = mutationVersion.value;
|
|
@@ -137,6 +150,7 @@ export function useConversations() {
|
|
|
137
150
|
mutatedConversationIds.value = [];
|
|
138
151
|
}
|
|
139
152
|
pruneDeletedConversationIds(data);
|
|
153
|
+
hasFetched.value = true;
|
|
140
154
|
} catch (err) {
|
|
141
155
|
const message = err instanceof Error ? err.message : "Erro ao carregar conversas";
|
|
142
156
|
error.value = message;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
let mediaCache = null;
|
|
2
|
+
function getMediaCache() {
|
|
3
|
+
mediaCache ??= useIDB({
|
|
4
|
+
storeName: "vault-media-cache",
|
|
5
|
+
version: 2
|
|
6
|
+
});
|
|
7
|
+
return mediaCache;
|
|
8
|
+
}
|
|
5
9
|
export function useMediaCache() {
|
|
10
|
+
const mediaCache2 = getMediaCache();
|
|
6
11
|
async function getCached(cacheKey) {
|
|
7
12
|
try {
|
|
8
|
-
const cachedData = await
|
|
13
|
+
const cachedData = await mediaCache2.get(cacheKey);
|
|
9
14
|
if (cachedData)
|
|
10
15
|
return cachedData;
|
|
11
16
|
return null;
|
|
@@ -15,13 +20,13 @@ export function useMediaCache() {
|
|
|
15
20
|
}
|
|
16
21
|
async function setCache(cacheKey, base64) {
|
|
17
22
|
try {
|
|
18
|
-
await
|
|
23
|
+
await mediaCache2.set(cacheKey, base64);
|
|
19
24
|
} catch {
|
|
20
25
|
}
|
|
21
26
|
}
|
|
22
27
|
async function removeFromCache(cacheKey) {
|
|
23
28
|
try {
|
|
24
|
-
await
|
|
29
|
+
await mediaCache2.remove(cacheKey);
|
|
25
30
|
} catch {
|
|
26
31
|
}
|
|
27
32
|
}
|
|
@@ -48,15 +48,11 @@ export function useWorkspaceSettings() {
|
|
|
48
48
|
});
|
|
49
49
|
}
|
|
50
50
|
function openModal(tab) {
|
|
51
|
-
if (embedConfig !== null)
|
|
52
|
-
return;
|
|
53
51
|
if (tab)
|
|
54
52
|
initialTab.value = tab;
|
|
55
53
|
isModalOpen.value = true;
|
|
56
54
|
}
|
|
57
55
|
function closeModal() {
|
|
58
|
-
if (embedConfig !== null)
|
|
59
|
-
return;
|
|
60
56
|
isModalOpen.value = false;
|
|
61
57
|
initialTab.value = null;
|
|
62
58
|
}
|
|
@@ -140,14 +140,15 @@ watch(() => props.conversationId, async (nextConversationId) => {
|
|
|
140
140
|
await ensureConversationLoaded(normalizedConversationId);
|
|
141
141
|
});
|
|
142
142
|
onMounted(async () => {
|
|
143
|
-
|
|
143
|
+
void fetchConversations();
|
|
144
144
|
if (!effectiveWorkspaceSettings.value) {
|
|
145
|
-
|
|
145
|
+
void fetchSettings();
|
|
146
146
|
}
|
|
147
|
-
await Promise.allSettled(pendingTasks);
|
|
148
147
|
isReady.value = true;
|
|
149
148
|
if (activeConversationId.value) {
|
|
150
149
|
await ensureConversationLoaded(activeConversationId.value);
|
|
150
|
+
} else {
|
|
151
|
+
resetConversation(false);
|
|
151
152
|
}
|
|
152
153
|
});
|
|
153
154
|
const MAX_DISMISSED_CHAT_IDS = 100;
|
|
@@ -12,7 +12,7 @@ defineProps({
|
|
|
12
12
|
gitHubButtonText: { type: String, required: true }
|
|
13
13
|
});
|
|
14
14
|
const emit = defineEmits(["update:searchQuery", "update:skillModalOpen", "update:skillRefInput", "removeSkill", "closeSkillModal", "handleAddSkillAndClose", "connectGitHub"]);
|
|
15
|
-
const githubIconUrl = "/github.svg";
|
|
15
|
+
const githubIconUrl = "/chat-assets/github.svg";
|
|
16
16
|
</script>
|
|
17
17
|
|
|
18
18
|
<template>
|
package/package.json
CHANGED
|
File without changes
|