@meistrari/chat-nuxt 1.2.1 → 1.2.3
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 +1 -10
- package/dist/module.json +1 -1
- package/dist/module.mjs +10 -1
- 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/useKnowledgeSources.js +1 -1
- package/dist/runtime/composables/useMediaCache.js +12 -7
- package/dist/runtime/plugins/markstream.d.ts +2 -0
- package/dist/runtime/plugins/markstream.js +5 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,22 +86,13 @@ Set `chatNuxt.validateConfig` to `'warn'` to report missing server config during
|
|
|
86
86
|
|
|
87
87
|
```vue
|
|
88
88
|
<!-- app.vue -->
|
|
89
|
-
<script setup lang="ts">
|
|
90
|
-
import { setDefaultMathOptions } from 'markstream-vue'
|
|
91
|
-
import 'markstream-vue/index.css'
|
|
92
|
-
import '@meistrari/chat-nuxt/assets/css/markstream.css'
|
|
93
|
-
import '@meistrari/chat-nuxt/assets/css/code-theme.css'
|
|
94
|
-
|
|
95
|
-
setDefaultMathOptions({ strictDelimiters: true })
|
|
96
|
-
</script>
|
|
97
|
-
|
|
98
89
|
<template>
|
|
99
90
|
<NuxtPage />
|
|
100
91
|
<AppStatusToast />
|
|
101
92
|
</template>
|
|
102
93
|
```
|
|
103
94
|
|
|
104
|
-
`AppStatusToast
|
|
95
|
+
`AppStatusToast`, Markstream styles, code block styles, and math delimiter defaults are auto-registered by the module.
|
|
105
96
|
|
|
106
97
|
### 4. Use it
|
|
107
98
|
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { existsSync, readFileSync, mkdirSync, symlinkSync } from 'node:fs';
|
|
2
2
|
import { createRequire } from 'node:module';
|
|
3
3
|
import { join, dirname } from 'node:path';
|
|
4
|
-
import { defineNuxtModule, createResolver, addImportsDir, addComponent, addComponentsDir } from 'nuxt/kit';
|
|
4
|
+
import { defineNuxtModule, createResolver, addPlugin, addImportsDir, addComponent, addComponentsDir } from 'nuxt/kit';
|
|
5
5
|
|
|
6
6
|
const localRequire = createRequire(import.meta.url);
|
|
7
7
|
const runtimeAliasPackages = [
|
|
@@ -260,6 +260,15 @@ const module$1 = defineNuxtModule({
|
|
|
260
260
|
rc.public = rc.public || {};
|
|
261
261
|
rc.public.agentApiUrl = rc.public.agentApiUrl || process.env.AGENT_API_URL || "";
|
|
262
262
|
validateRuntimeConfig(rc, options.validateConfig ?? false);
|
|
263
|
+
nuxt.options.css = nuxt.options.css || [];
|
|
264
|
+
nuxt.options.css.push(
|
|
265
|
+
_chatNuxtRequire.resolve("markstream-vue/index.css"),
|
|
266
|
+
join(runtimeDir, "assets/css/markstream.css"),
|
|
267
|
+
join(runtimeDir, "assets/css/code-theme.css")
|
|
268
|
+
);
|
|
269
|
+
addPlugin({
|
|
270
|
+
src: join(runtimeDir, "plugins/markstream")
|
|
271
|
+
});
|
|
263
272
|
addImportsDir(join(runtimeDir, "composables"));
|
|
264
273
|
addImportsDir(join(runtimeDir, "utils"));
|
|
265
274
|
addComponent({
|
|
@@ -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
|
}
|
|
@@ -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
|
}
|