@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
package/README.md
CHANGED
|
@@ -5,9 +5,27 @@ Nuxt module that adds a complete AI chat interface to your app. Powered by Tela'
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @meistrari/chat-nuxt
|
|
8
|
+
pnpm add @meistrari/chat-nuxt
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
### Required: Vue dedupe via pnpm overrides
|
|
12
|
+
|
|
13
|
+
`@meistrari/tela-build` pins `vue@3.5.13` as a direct dependency, which collides with the Vue that Nuxt installs. Without an override, pnpm installs two Vue copies and you'll hit runtime errors such as `root.ce._hasShadowRoot is not a function` when custom elements register against one Vue and mount against the other.
|
|
14
|
+
|
|
15
|
+
Until tela-build is published with Vue as a peer dependency, pin a single Vue version in your consumer `package.json`:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"pnpm": {
|
|
20
|
+
"overrides": {
|
|
21
|
+
"vue": "3.5.33"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Keep this entry until `@meistrari/tela-build` moves Vue to `peerDependencies` — at that point the override becomes unnecessary and should be removed.
|
|
28
|
+
|
|
11
29
|
## Setup
|
|
12
30
|
|
|
13
31
|
### 1. Register the modules
|
|
@@ -15,8 +33,6 @@ pnpm add @meistrari/chat-nuxt @meistrari/auth-nuxt @meistrari/tela-build markstr
|
|
|
15
33
|
```typescript
|
|
16
34
|
// nuxt.config.ts
|
|
17
35
|
export default defineNuxtConfig({
|
|
18
|
-
extends: ['@meistrari/tela-build'],
|
|
19
|
-
|
|
20
36
|
modules: [
|
|
21
37
|
'@meistrari/auth-nuxt', // must come before chat-nuxt
|
|
22
38
|
'@meistrari/chat-nuxt',
|
|
@@ -24,6 +40,10 @@ export default defineNuxtConfig({
|
|
|
24
40
|
|
|
25
41
|
ssr: false,
|
|
26
42
|
|
|
43
|
+
chatNuxt: {
|
|
44
|
+
validateConfig: 'warn',
|
|
45
|
+
},
|
|
46
|
+
|
|
27
47
|
telaAuth: {
|
|
28
48
|
apiUrl: process.env.AUTH_API_URL ?? '',
|
|
29
49
|
application: {
|
|
@@ -58,6 +78,9 @@ The module injects these into Nuxt's `runtimeConfig` automatically — just set
|
|
|
58
78
|
| `AGENT_API_URL` | Agent API endpoint |
|
|
59
79
|
| `VAULT_URL` | Vault service URL |
|
|
60
80
|
| `VAULT_S3_BUCKET` | Vault S3 bucket name |
|
|
81
|
+
| `CHAT_APP_SERVICE_KEY` | Service key used when resolving workspace credentials |
|
|
82
|
+
|
|
83
|
+
Set `chatNuxt.validateConfig` to `'warn'` to report missing server config during Nuxt setup, or `'error'` to fail fast in CI or production builds. The check is disabled by default because many deployments inject runtime config after build.
|
|
61
84
|
|
|
62
85
|
### 3. Setup `app.vue`
|
|
63
86
|
|
|
@@ -91,7 +114,7 @@ const workspaceId = computed(() => activeOrganization.value?.id ?? null)
|
|
|
91
114
|
|
|
92
115
|
<template>
|
|
93
116
|
<div v-if="workspaceId" h-screen>
|
|
94
|
-
<
|
|
117
|
+
<MeistrariChatEmbed :workspace-id="workspaceId" />
|
|
95
118
|
</div>
|
|
96
119
|
</template>
|
|
97
120
|
```
|
|
@@ -110,7 +133,7 @@ The main use case: drop the chat inside your existing app UI.
|
|
|
110
133
|
<main>
|
|
111
134
|
<!-- Chat embedded in a card -->
|
|
112
135
|
<div style="height: 600px" class="rounded-2xl overflow-hidden border">
|
|
113
|
-
<
|
|
136
|
+
<MeistrariChatEmbed
|
|
114
137
|
v-model:conversation-id="activeConversation"
|
|
115
138
|
:workspace-id="workspaceId"
|
|
116
139
|
:hide-sidebar="true"
|
|
@@ -127,7 +150,7 @@ Key props for embedding:
|
|
|
127
150
|
- **`v-model:conversation-id`** — sync the active conversation with your app's state
|
|
128
151
|
- **`:initial-conversation-id`** — open a specific conversation on mount
|
|
129
152
|
|
|
130
|
-
## `<
|
|
153
|
+
## `<MeistrariChatEmbed>` Props
|
|
131
154
|
|
|
132
155
|
| Prop | Type | Default | Description |
|
|
133
156
|
|------|------|---------|-------------|
|
|
@@ -179,7 +202,7 @@ onMounted(async () => {
|
|
|
179
202
|
</script>
|
|
180
203
|
```
|
|
181
204
|
|
|
182
|
-
3. Pass flags to `<
|
|
205
|
+
3. Pass flags to `<MeistrariChatEmbed>`:
|
|
183
206
|
|
|
184
207
|
```vue
|
|
185
208
|
<script setup lang="ts">
|
|
@@ -194,14 +217,14 @@ const features = computed(() => ({
|
|
|
194
217
|
</script>
|
|
195
218
|
|
|
196
219
|
<template>
|
|
197
|
-
<
|
|
220
|
+
<MeistrariChatEmbed :workspace-id="workspaceId" :features="features" />
|
|
198
221
|
</template>
|
|
199
222
|
```
|
|
200
223
|
|
|
201
224
|
Without PostHog, you can pass features statically:
|
|
202
225
|
|
|
203
226
|
```vue
|
|
204
|
-
<
|
|
227
|
+
<MeistrariChatEmbed :workspace-id="workspaceId" :features="{ showUsageTab: true }" />
|
|
205
228
|
```
|
|
206
229
|
|
|
207
230
|
## Optional: Custom Workspace Settings
|
|
@@ -215,7 +238,7 @@ You can override this in two ways:
|
|
|
215
238
|
Pass settings directly from your host app:
|
|
216
239
|
|
|
217
240
|
```vue
|
|
218
|
-
<
|
|
241
|
+
<MeistrariChatEmbed
|
|
219
242
|
:workspace-id="workspaceId"
|
|
220
243
|
:workspace-settings="{
|
|
221
244
|
workspaceId: 'ws_123',
|
|
@@ -254,6 +277,49 @@ export default async function resolveWorkspaceSettings(
|
|
|
254
277
|
}
|
|
255
278
|
```
|
|
256
279
|
|
|
280
|
+
## `<ChatConfigurationModal>`
|
|
281
|
+
|
|
282
|
+
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.
|
|
283
|
+
|
|
284
|
+
```vue
|
|
285
|
+
<script setup lang="ts">
|
|
286
|
+
import type { ChatConfigurationTab } from '@meistrari/chat-nuxt/types/workspace-settings'
|
|
287
|
+
|
|
288
|
+
const open = ref(false)
|
|
289
|
+
const initialTab = ref<ChatConfigurationTab>('personalization')
|
|
290
|
+
|
|
291
|
+
function openSettings(tab: ChatConfigurationTab = 'personalization') {
|
|
292
|
+
initialTab.value = tab
|
|
293
|
+
open.value = true
|
|
294
|
+
}
|
|
295
|
+
</script>
|
|
296
|
+
|
|
297
|
+
<template>
|
|
298
|
+
<button @click="openSettings()">
|
|
299
|
+
Configurações
|
|
300
|
+
</button>
|
|
301
|
+
|
|
302
|
+
<ChatConfigurationModal
|
|
303
|
+
v-model:open="open"
|
|
304
|
+
:initial-tab="initialTab"
|
|
305
|
+
/>
|
|
306
|
+
</template>
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
| Prop | Type | Default | Description |
|
|
310
|
+
|------|------|---------|-------------|
|
|
311
|
+
| `open` | `boolean` | — | Modal visibility (supports `v-model:open`) |
|
|
312
|
+
| `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 |
|
|
313
|
+
| `initialTab` | `ChatConfigurationTab` | `'personalization'` | Tab to open on |
|
|
314
|
+
| `saving` | `boolean` | `false` | Host-controlled spinner/disable while persistence is in flight |
|
|
315
|
+
|
|
316
|
+
| Event | Payload | Description |
|
|
317
|
+
|-------|---------|-------------|
|
|
318
|
+
| `update:open` | `boolean` | Modal open state changed |
|
|
319
|
+
| `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 |
|
|
320
|
+
|
|
321
|
+
The `credentials` tab manages its own data via the module's `/api/workspace/credentials` endpoints and is never part of the `save` payload.
|
|
322
|
+
|
|
257
323
|
## What's Included
|
|
258
324
|
|
|
259
325
|
The module auto-registers everything — no manual imports needed:
|
|
@@ -263,10 +329,28 @@ The module auto-registers everything — no manual imports needed:
|
|
|
263
329
|
- **Server routes**: conversation CRUD, message streaming, workspace settings, vault file storage, GitHub integration
|
|
264
330
|
- **Database**: conversations, messages, usage tracking (Drizzle ORM + PostgreSQL)
|
|
265
331
|
|
|
266
|
-
##
|
|
332
|
+
## Package Dependencies
|
|
333
|
+
|
|
334
|
+
Installing `@meistrari/chat-nuxt` installs the runtime packages used by the layer. The host Nuxt app still owns the Nuxt and Vue versions.
|
|
267
335
|
|
|
268
336
|
| Package | Version | Purpose |
|
|
269
337
|
|---------|---------|---------|
|
|
270
338
|
| `@meistrari/auth-nuxt` | `^3.4.1` | Authentication (required) |
|
|
271
339
|
| `@meistrari/tela-build` | `^1.30.0` | UI component library (Nuxt layer) |
|
|
340
|
+
| `@sentry/nuxt` | `^10.0.0` | Client-side error capture used by chat composables |
|
|
341
|
+
| `@iconify/vue` | `^5.0.0` | Icon rendering support |
|
|
342
|
+
| `@vueuse/core` | `^12.8.0` | Runtime composables used by chat UI |
|
|
343
|
+
| `@vueuse/components` | `^12.8.0` | VueUse component peer expected by the shared runtime |
|
|
344
|
+
| `h3` | `^1.15.0` | Server route utilities provided by Nuxt/Nitro |
|
|
272
345
|
| `markstream-vue` | `0.0.3-beta.6` | Markdown streaming renderer |
|
|
346
|
+
| `motion` | `^11.13.0` | Animation component runtime |
|
|
347
|
+
| `nitropack` | `^2.10.0` | Runtime config and task utilities provided by Nuxt/Nitro |
|
|
348
|
+
| `virtua` | `^0.42.0` | Virtualized list runtime expected by shared UI |
|
|
349
|
+
| `vue-i18n` | `^11.0.0` | Internationalization runtime expected by shared UI |
|
|
350
|
+
|
|
351
|
+
Peer dependencies:
|
|
352
|
+
|
|
353
|
+
| Package | Version | Purpose |
|
|
354
|
+
|---------|---------|---------|
|
|
355
|
+
| `nuxt` | `^3.17.0` | Host framework |
|
|
356
|
+
| `vue` | `^3.5.0` | Host Vue runtime |
|
package/dist/module.d.mts
CHANGED
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, symlinkSync } from 'node:fs';
|
|
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, addComponentsDir } from 'nuxt/kit';
|
|
4
|
+
import { defineNuxtModule, createResolver, addImportsDir, addComponent, addComponentsDir } from 'nuxt/kit';
|
|
5
5
|
|
|
6
6
|
const localRequire = createRequire(import.meta.url);
|
|
7
7
|
const runtimeAliasPackages = [
|
|
@@ -37,7 +37,7 @@ function isExpectedResolutionError(error) {
|
|
|
37
37
|
}
|
|
38
38
|
return error.code === "MODULE_NOT_FOUND" || error.code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
|
|
39
39
|
}
|
|
40
|
-
function resolvePackageRoot(resolver, packageName) {
|
|
40
|
+
function resolvePackageRoot$1(resolver, packageName) {
|
|
41
41
|
try {
|
|
42
42
|
return dirname(resolver.resolve(`${packageName}/package.json`));
|
|
43
43
|
} catch (error) {
|
|
@@ -81,7 +81,7 @@ function resolveTelaBuildLayer() {
|
|
|
81
81
|
return localPath;
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
-
const telaBuildRoot = resolvePackageRoot(localRequire, "@meistrari/tela-build");
|
|
84
|
+
const telaBuildRoot = resolvePackageRoot$1(localRequire, "@meistrari/tela-build");
|
|
85
85
|
if (!telaBuildRoot) {
|
|
86
86
|
throw new Error(
|
|
87
87
|
"[@meistrari/chat-nuxt] Cannot resolve @meistrari/tela-build. Ensure it is installed."
|
|
@@ -95,19 +95,19 @@ function resolveRuntimeAliases(telaBuildPath) {
|
|
|
95
95
|
const telaBuildRequire = createRequire(join(telaBuildPath, "package.json"));
|
|
96
96
|
const vueRuntimeEntry = resolvePackageEntry(nuxtRequire, "vue/dist/vue.runtime.esm-bundler.js");
|
|
97
97
|
const aliases = [
|
|
98
|
-
["vue", vueRuntimeEntry ?? resolvePackageRoot(nuxtRequire, "vue")],
|
|
98
|
+
["vue", vueRuntimeEntry ?? resolvePackageRoot$1(nuxtRequire, "vue")],
|
|
99
99
|
["vue/dist/vue.runtime.esm-bundler.js", vueRuntimeEntry],
|
|
100
|
-
["@vue/runtime-core", resolvePackageEntry(nuxtRequire, "@vue/runtime-core/dist/runtime-core.esm-bundler.js") ?? resolvePackageRoot(nuxtRequire, "@vue/runtime-core")],
|
|
101
|
-
["@vue/runtime-dom", resolvePackageEntry(nuxtRequire, "@vue/runtime-dom/dist/runtime-dom.esm-bundler.js") ?? resolvePackageRoot(nuxtRequire, "@vue/runtime-dom")],
|
|
102
|
-
["@vue/reactivity", resolvePackageEntry(nuxtRequire, "@vue/reactivity/dist/reactivity.esm-bundler.js") ?? resolvePackageRoot(nuxtRequire, "@vue/reactivity")],
|
|
103
|
-
["@vue/shared", resolvePackageEntry(nuxtRequire, "@vue/shared/dist/shared.esm-bundler.js") ?? resolvePackageRoot(nuxtRequire, "@vue/shared")],
|
|
104
|
-
["vue-router", resolvePackageEntry(nuxtRequire, "vue-router/dist/vue-router.mjs") ?? resolvePackageRoot(nuxtRequire, "vue-router")],
|
|
105
|
-
["@vueuse/core", resolvePackageRoot(localRequire, "@vueuse/core")],
|
|
106
|
-
["@vueuse/components", resolvePackageRoot(localRequire, "@vueuse/components")],
|
|
107
|
-
["@vueuse/shared", resolvePackageRoot(vueUseCoreRequire, "@vueuse/shared")],
|
|
108
|
-
["reka-ui", resolvePackageRoot(telaBuildRequire, "reka-ui")],
|
|
109
|
-
["radix-vue", resolvePackageRoot(telaBuildRequire, "radix-vue")],
|
|
110
|
-
["@floating-ui/vue", resolvePackageRoot(telaBuildRequire, "@floating-ui/vue")]
|
|
100
|
+
["@vue/runtime-core", resolvePackageEntry(nuxtRequire, "@vue/runtime-core/dist/runtime-core.esm-bundler.js") ?? resolvePackageRoot$1(nuxtRequire, "@vue/runtime-core")],
|
|
101
|
+
["@vue/runtime-dom", resolvePackageEntry(nuxtRequire, "@vue/runtime-dom/dist/runtime-dom.esm-bundler.js") ?? resolvePackageRoot$1(nuxtRequire, "@vue/runtime-dom")],
|
|
102
|
+
["@vue/reactivity", resolvePackageEntry(nuxtRequire, "@vue/reactivity/dist/reactivity.esm-bundler.js") ?? resolvePackageRoot$1(nuxtRequire, "@vue/reactivity")],
|
|
103
|
+
["@vue/shared", resolvePackageEntry(nuxtRequire, "@vue/shared/dist/shared.esm-bundler.js") ?? resolvePackageRoot$1(nuxtRequire, "@vue/shared")],
|
|
104
|
+
["vue-router", resolvePackageEntry(nuxtRequire, "vue-router/dist/vue-router.mjs") ?? resolvePackageRoot$1(nuxtRequire, "vue-router")],
|
|
105
|
+
["@vueuse/core", resolvePackageRoot$1(localRequire, "@vueuse/core")],
|
|
106
|
+
["@vueuse/components", resolvePackageRoot$1(localRequire, "@vueuse/components")],
|
|
107
|
+
["@vueuse/shared", resolvePackageRoot$1(vueUseCoreRequire, "@vueuse/shared")],
|
|
108
|
+
["reka-ui", resolvePackageRoot$1(telaBuildRequire, "reka-ui")],
|
|
109
|
+
["radix-vue", resolvePackageRoot$1(telaBuildRequire, "radix-vue")],
|
|
110
|
+
["@floating-ui/vue", resolvePackageRoot$1(telaBuildRequire, "@floating-ui/vue")]
|
|
111
111
|
];
|
|
112
112
|
const resolvedAliases = aliases.reduce((acc, [name, resolvedPath]) => {
|
|
113
113
|
if (resolvedPath) {
|
|
@@ -148,6 +148,20 @@ function resolveWorkspaceSettingsResolverEntry(srcDir, fallbackResolverBase) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
const _chatNuxtRequire = createRequire(import.meta.url);
|
|
151
|
+
const requiredRuntimeConfigKeys = [
|
|
152
|
+
"databaseUrl",
|
|
153
|
+
"telaApiUrl",
|
|
154
|
+
"telaApiKey",
|
|
155
|
+
"authApiUrl",
|
|
156
|
+
"authApiSecret",
|
|
157
|
+
"agentApiUrl",
|
|
158
|
+
"authJwksUrl",
|
|
159
|
+
"vaultUrl",
|
|
160
|
+
"chatAppServiceKey"
|
|
161
|
+
];
|
|
162
|
+
function resolvePackageRoot(packageName) {
|
|
163
|
+
return dirname(_chatNuxtRequire.resolve(`${packageName}/package.json`));
|
|
164
|
+
}
|
|
151
165
|
function ensureIconifyPackages(consumerRoot) {
|
|
152
166
|
const packages = ["@iconify-json/ph"];
|
|
153
167
|
for (const pkg of packages) {
|
|
@@ -156,18 +170,34 @@ function ensureIconifyPackages(consumerRoot) {
|
|
|
156
170
|
continue;
|
|
157
171
|
}
|
|
158
172
|
try {
|
|
159
|
-
const realPath = dirname(_chatNuxtRequire.resolve(`${pkg}/package.json`));
|
|
160
173
|
mkdirSync(dirname(consumerPath), { recursive: true });
|
|
161
|
-
symlinkSync(
|
|
174
|
+
symlinkSync(resolvePackageRoot(pkg), consumerPath);
|
|
162
175
|
} catch (err) {
|
|
163
|
-
console.warn(`[@meistrari/chat-nuxt] Failed to
|
|
176
|
+
console.warn(`[@meistrari/chat-nuxt] Failed to link ${pkg} into the consumer app. Icons may not render.`, err);
|
|
164
177
|
}
|
|
165
178
|
}
|
|
166
179
|
}
|
|
180
|
+
function validateRuntimeConfig(runtimeConfig, mode) {
|
|
181
|
+
if (!mode) {
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const missingKeys = requiredRuntimeConfigKeys.filter((key) => !runtimeConfig[key]);
|
|
185
|
+
if (missingKeys.length === 0) {
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const message = `[@meistrari/chat-nuxt] Missing runtime config: ${missingKeys.join(", ")}. Set these values in runtimeConfig or the matching environment variables before using chat server routes.`;
|
|
189
|
+
if (mode === "error") {
|
|
190
|
+
throw new Error(message);
|
|
191
|
+
}
|
|
192
|
+
console.warn(message);
|
|
193
|
+
}
|
|
167
194
|
function isAuthModuleEntry(entry) {
|
|
168
195
|
if (typeof entry === "string") {
|
|
169
196
|
return entry === "@meistrari/auth-nuxt";
|
|
170
197
|
}
|
|
198
|
+
if (entry && typeof entry === "object" && "src" in entry) {
|
|
199
|
+
return entry.src === "@meistrari/auth-nuxt";
|
|
200
|
+
}
|
|
171
201
|
if (Array.isArray(entry)) {
|
|
172
202
|
return entry[0] === "@meistrari/auth-nuxt";
|
|
173
203
|
}
|
|
@@ -176,16 +206,19 @@ function isAuthModuleEntry(entry) {
|
|
|
176
206
|
const module$1 = defineNuxtModule({
|
|
177
207
|
meta: {
|
|
178
208
|
name: "@meistrari/chat-nuxt",
|
|
179
|
-
configKey: "
|
|
209
|
+
configKey: "chatNuxt"
|
|
180
210
|
},
|
|
181
|
-
|
|
182
|
-
|
|
211
|
+
defaults: {
|
|
212
|
+
validateConfig: false
|
|
213
|
+
},
|
|
214
|
+
setup(options, nuxt) {
|
|
183
215
|
const hasAuthModule = (nuxt.options.modules ?? []).some(isAuthModuleEntry);
|
|
184
216
|
if (!hasAuthModule) {
|
|
185
217
|
throw new Error(
|
|
186
218
|
'[@meistrari/chat-nuxt] Missing required module "@meistrari/auth-nuxt". Install and enable it so useTelaApplicationAuth() and event.context.auth are available.'
|
|
187
219
|
);
|
|
188
220
|
}
|
|
221
|
+
ensureIconifyPackages(nuxt.options.rootDir);
|
|
189
222
|
const resolver = createResolver(import.meta.url);
|
|
190
223
|
const runtimeDir = resolver.resolve("./runtime");
|
|
191
224
|
const workspaceSettingsResolverEntry = resolveWorkspaceSettingsResolverEntry(
|
|
@@ -201,8 +234,16 @@ const module$1 = defineNuxtModule({
|
|
|
201
234
|
nuxt.options.alias = {
|
|
202
235
|
...nuxt.options.alias,
|
|
203
236
|
"#chat-workspace-settings-resolver": workspaceSettingsResolverEntry,
|
|
204
|
-
"#chat-runtime": runtimeDir
|
|
237
|
+
"#chat-runtime": runtimeDir,
|
|
238
|
+
"@iconify-json/ph": resolvePackageRoot("@iconify-json/ph")
|
|
205
239
|
};
|
|
240
|
+
if (nuxt.options.imports !== false) {
|
|
241
|
+
nuxt.options.imports = nuxt.options.imports || {};
|
|
242
|
+
nuxt.options.imports.transform = nuxt.options.imports.transform || {};
|
|
243
|
+
nuxt.options.imports.transform.include = nuxt.options.imports.transform.include || [];
|
|
244
|
+
const runtimeDirRegExp = new RegExp(runtimeDir.replace(/\\/g, "/").replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
|
|
245
|
+
nuxt.options.imports.transform.include.push(runtimeDirRegExp);
|
|
246
|
+
}
|
|
206
247
|
const rc = nuxt.options.runtimeConfig;
|
|
207
248
|
rc.databaseUrl = rc.databaseUrl || process.env.DATABASE_URL || "";
|
|
208
249
|
rc.telaApiUrl = rc.telaApiUrl || process.env.TELA_API_URL || "";
|
|
@@ -216,8 +257,14 @@ const module$1 = defineNuxtModule({
|
|
|
216
257
|
rc.chatAppServiceKey = rc.chatAppServiceKey || process.env.CHAT_APP_SERVICE_KEY || "";
|
|
217
258
|
rc.public = rc.public || {};
|
|
218
259
|
rc.public.agentApiUrl = rc.public.agentApiUrl || process.env.AGENT_API_URL || "";
|
|
260
|
+
validateRuntimeConfig(rc, options.validateConfig ?? false);
|
|
219
261
|
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
220
262
|
addImportsDir(resolver.resolve("./runtime/utils"));
|
|
263
|
+
addComponent({
|
|
264
|
+
name: "MeistrariChatEmbed",
|
|
265
|
+
filePath: resolver.resolve("./runtime/components/MeistrariChatEmbed.vue"),
|
|
266
|
+
priority: 1e3
|
|
267
|
+
});
|
|
221
268
|
addComponentsDir({
|
|
222
269
|
path: resolver.resolve("./runtime/components")
|
|
223
270
|
});
|
|
@@ -243,8 +290,28 @@ const module$1 = defineNuxtModule({
|
|
|
243
290
|
...config.resolve.dedupe || [],
|
|
244
291
|
...runtimeAliasDedupe
|
|
245
292
|
]));
|
|
293
|
+
config.plugins.push({
|
|
294
|
+
name: "@meistrari/chat-nuxt:elkjs-umd-interop",
|
|
295
|
+
enforce: "pre",
|
|
296
|
+
apply: "serve",
|
|
297
|
+
load(id) {
|
|
298
|
+
const cleanId = id.split("?")[0] ?? id;
|
|
299
|
+
if (!cleanId.endsWith("/elkjs/lib/elk.bundled.js")) {
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
try {
|
|
303
|
+
const source = readFileSync(cleanId, "utf8");
|
|
304
|
+
return `${source}
|
|
305
|
+
export default globalThis.ELK;
|
|
306
|
+
`;
|
|
307
|
+
} catch {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
});
|
|
246
312
|
});
|
|
247
313
|
const serverDir = resolver.resolve("./runtime/server");
|
|
314
|
+
const publicFilesDir = resolver.resolve("./runtime/public/files");
|
|
248
315
|
nuxt.hook("nitro:config", (nitroConfig) => {
|
|
249
316
|
nitroConfig.scanDirs = nitroConfig.scanDirs || [];
|
|
250
317
|
nitroConfig.scanDirs.push(serverDir);
|
|
@@ -253,6 +320,12 @@ const module$1 = defineNuxtModule({
|
|
|
253
320
|
"#chat-runtime": runtimeDir,
|
|
254
321
|
"#chat-workspace-settings-resolver": workspaceSettingsResolverEntry
|
|
255
322
|
};
|
|
323
|
+
nitroConfig.publicAssets = nitroConfig.publicAssets || [];
|
|
324
|
+
nitroConfig.publicAssets.push({
|
|
325
|
+
dir: publicFilesDir,
|
|
326
|
+
baseURL: "/chat-files",
|
|
327
|
+
maxAge: 60 * 60 * 24 * 7
|
|
328
|
+
});
|
|
256
329
|
});
|
|
257
330
|
}
|
|
258
331
|
});
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversations: DeepReadonly<Conversation[]>;
|
|
5
5
|
currentId?: string;
|
|
6
6
|
getMemberImage?: (userId: string) => string | undefined;
|
|
7
|
+
loading?: boolean;
|
|
7
8
|
};
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
10
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { groupConversationsByDate } from "../../utils/format-time";
|
|
3
3
|
import { exportConversationToMarkdown } from "../../utils/export-conversation";
|
|
4
|
+
import { conversationListSkeletonRows } from "../../utils/conversation-list-skeleton";
|
|
4
5
|
const props = defineProps({
|
|
5
6
|
conversations: { type: null, required: true },
|
|
6
7
|
currentId: { type: String, required: false },
|
|
7
|
-
getMemberImage: { type: Function, required: false }
|
|
8
|
+
getMemberImage: { type: Function, required: false },
|
|
9
|
+
loading: { type: Boolean, required: false }
|
|
8
10
|
});
|
|
9
11
|
const chatApi = useChatApi();
|
|
10
12
|
const { deleteConversation, renameConversation, duplicateConversation } = useConversations();
|
|
13
|
+
const { setConversation } = useChat();
|
|
11
14
|
const router = useRouter();
|
|
12
15
|
const groupedConversations = computed(() => {
|
|
13
16
|
return groupConversationsByDate(props.conversations);
|
|
@@ -25,6 +28,7 @@ async function handleRename(id, title) {
|
|
|
25
28
|
async function handleDuplicate(id) {
|
|
26
29
|
const duplicated = await duplicateConversation(id);
|
|
27
30
|
if (duplicated) {
|
|
31
|
+
setConversation(duplicated);
|
|
28
32
|
router.push(`/${duplicated.id}`);
|
|
29
33
|
}
|
|
30
34
|
}
|
|
@@ -43,7 +47,23 @@ async function handleExport(id) {
|
|
|
43
47
|
|
|
44
48
|
<template>
|
|
45
49
|
<div flex="~ col" gap-16px>
|
|
46
|
-
<div v-if="conversations.length === 0"
|
|
50
|
+
<div v-if="loading && conversations.length === 0" flex="~ col" gap-4px>
|
|
51
|
+
<div h-20px flex items-center pl-12px pr-4px mb-4px>
|
|
52
|
+
<TelaSkeleton rounded-4px bg-neutral-200 style="width: 68px; height: 12px;" />
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
<div flex="~ col" gap-1px>
|
|
56
|
+
<div
|
|
57
|
+
v-for="row in conversationListSkeletonRows"
|
|
58
|
+
:key="row.id"
|
|
59
|
+
flex items-center h-32px px-8px rounded-8px
|
|
60
|
+
>
|
|
61
|
+
<TelaSkeleton rounded-6px bg-neutral-200 :style="{ width: row.width, height: '13px' }" />
|
|
62
|
+
</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>
|
|
65
|
+
|
|
66
|
+
<div v-else-if="conversations.length === 0" p-16px text-center>
|
|
47
67
|
<p text-14px text-neutral-400>
|
|
48
68
|
Nenhuma conversa ainda
|
|
49
69
|
</p>
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversations: DeepReadonly<Conversation[]>;
|
|
5
5
|
currentId?: string;
|
|
6
6
|
getMemberImage?: (userId: string) => string | undefined;
|
|
7
|
+
loading?: boolean;
|
|
7
8
|
};
|
|
8
9
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
9
10
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Message } from '../../types/chat.js';
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
messages: readonly Message[];
|
|
4
|
+
loading?: boolean;
|
|
4
5
|
};
|
|
5
6
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
6
7
|
retry: (messageId: string) => any;
|
|
@@ -1,9 +1,16 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
const props = defineProps({
|
|
3
|
-
messages: { type: Array, required: true }
|
|
3
|
+
messages: { type: Array, required: true },
|
|
4
|
+
loading: { type: Boolean, required: false }
|
|
4
5
|
});
|
|
5
6
|
const emit = defineEmits(["retry"]);
|
|
6
7
|
const containerRef = ref(null);
|
|
8
|
+
const skeletonMessages = [
|
|
9
|
+
{ id: "user-1", align: "end", width: "58%", height: "44px" },
|
|
10
|
+
{ id: "assistant-1", align: "start", width: "92%", height: "116px" },
|
|
11
|
+
{ id: "user-2", align: "end", width: "46%", height: "44px" },
|
|
12
|
+
{ id: "assistant-2", align: "start", width: "84%", height: "92px" }
|
|
13
|
+
];
|
|
7
14
|
function scrollToBottom() {
|
|
8
15
|
nextTick(() => {
|
|
9
16
|
if (containerRef.value) {
|
|
@@ -23,7 +30,21 @@ onMounted(scrollToBottom);
|
|
|
23
30
|
pt-88px pb-24px px-24px
|
|
24
31
|
>
|
|
25
32
|
<div max-w-800px mx-auto>
|
|
26
|
-
<div flex="~ col" gap-16px>
|
|
33
|
+
<div v-if="loading" flex="~ col" gap-16px>
|
|
34
|
+
<div
|
|
35
|
+
v-for="message in skeletonMessages"
|
|
36
|
+
:key="message.id"
|
|
37
|
+
flex
|
|
38
|
+
:class="message.align === 'end' ? 'justify-end' : 'justify-start'"
|
|
39
|
+
>
|
|
40
|
+
<TelaSkeleton
|
|
41
|
+
rounded-16px
|
|
42
|
+
:style="{ width: message.width, height: message.height }"
|
|
43
|
+
/>
|
|
44
|
+
</div>
|
|
45
|
+
</div>
|
|
46
|
+
|
|
47
|
+
<div v-else flex="~ col" gap-16px>
|
|
27
48
|
<ChatMessageBubble
|
|
28
49
|
v-for="message in messages"
|
|
29
50
|
:key="message.id"
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Message } from '../../types/chat.js';
|
|
2
2
|
type __VLS_Props = {
|
|
3
3
|
messages: readonly Message[];
|
|
4
|
+
loading?: boolean;
|
|
4
5
|
};
|
|
5
6
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
6
7
|
retry: (messageId: string) => any;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Message } from '../types/chat.js';
|
|
1
|
+
import type { Conversation, ConversationWithMessages, Message } from '../types/chat.js';
|
|
2
2
|
export declare function useChat(): {
|
|
3
3
|
currentConversation: any;
|
|
4
4
|
messages: any;
|
|
@@ -11,6 +11,7 @@ export declare function useChat(): {
|
|
|
11
11
|
generatingTitle: any;
|
|
12
12
|
animatedTitle: any;
|
|
13
13
|
loadConversation: (id: string) => Promise<void>;
|
|
14
|
+
setConversation: (conv: Conversation | ConversationWithMessages) => void;
|
|
14
15
|
sendMessage: (content: string, files?: {
|
|
15
16
|
url: string;
|
|
16
17
|
name: string;
|
|
@@ -144,8 +144,29 @@ function parseReasoningFromPolling(reasoning) {
|
|
|
144
144
|
}
|
|
145
145
|
export function useChat() {
|
|
146
146
|
const chatApi = useChatApi();
|
|
147
|
-
const
|
|
148
|
-
const
|
|
147
|
+
const embedConfig = useEmbedConfig();
|
|
148
|
+
const { user: authUser, activeOrganization } = useTelaApplicationAuth();
|
|
149
|
+
const chatScope = computed(() => embedConfig?.workspaceId.value.trim() || activeOrganization.value?.id?.trim() || "default");
|
|
150
|
+
const currentConversationBuckets = useState("chat-current-conversation", () => ({}));
|
|
151
|
+
const messageBuckets = useState("chat-messages", () => ({}));
|
|
152
|
+
const currentConversation = computed({
|
|
153
|
+
get: () => currentConversationBuckets.value[chatScope.value] ?? null,
|
|
154
|
+
set: (value) => {
|
|
155
|
+
currentConversationBuckets.value = {
|
|
156
|
+
...currentConversationBuckets.value,
|
|
157
|
+
[chatScope.value]: value
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
});
|
|
161
|
+
const messages = computed({
|
|
162
|
+
get: () => messageBuckets.value[chatScope.value] ?? [],
|
|
163
|
+
set: (value) => {
|
|
164
|
+
messageBuckets.value = {
|
|
165
|
+
...messageBuckets.value,
|
|
166
|
+
[chatScope.value]: value
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
});
|
|
149
170
|
const loading = ref(false);
|
|
150
171
|
const sending = ref(false);
|
|
151
172
|
const error = ref(null);
|
|
@@ -213,6 +234,13 @@ export function useChat() {
|
|
|
213
234
|
interval: 500,
|
|
214
235
|
stopCondition
|
|
215
236
|
});
|
|
237
|
+
const setConversation = (conv) => {
|
|
238
|
+
const conversationMessages = "messages" in conv ? conv.messages : [];
|
|
239
|
+
currentConversation.value = { ...conv, messages: conversationMessages };
|
|
240
|
+
messages.value = conversationMessages;
|
|
241
|
+
titleGenerated.value = false;
|
|
242
|
+
error.value = null;
|
|
243
|
+
};
|
|
216
244
|
const loadConversation = async (id) => {
|
|
217
245
|
loading.value = true;
|
|
218
246
|
error.value = null;
|
|
@@ -258,7 +286,7 @@ export function useChat() {
|
|
|
258
286
|
files: filesWithSource,
|
|
259
287
|
externalUuid: null,
|
|
260
288
|
ttft: null,
|
|
261
|
-
createdBy: null,
|
|
289
|
+
createdBy: authUser.value?.email ?? null,
|
|
262
290
|
createdAt: /* @__PURE__ */ new Date(),
|
|
263
291
|
updatedAt: null
|
|
264
292
|
};
|
|
@@ -500,6 +528,7 @@ export function useChat() {
|
|
|
500
528
|
generatingTitle: readonly(generatingTitle),
|
|
501
529
|
animatedTitle: readonly(animatedTitle),
|
|
502
530
|
loadConversation,
|
|
531
|
+
setConversation,
|
|
503
532
|
sendMessage,
|
|
504
533
|
retryMessage,
|
|
505
534
|
cancelConversation,
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
export function useChatApi() {
|
|
2
2
|
const embedConfig = useEmbedConfig();
|
|
3
|
+
const { activeOrganization } = useTelaApplicationAuth();
|
|
3
4
|
function buildHeaders(headers) {
|
|
4
5
|
const mergedHeaders = {
|
|
5
6
|
...headers ?? {}
|
|
6
7
|
};
|
|
7
|
-
const workspaceId = embedConfig?.workspaceId.value.trim();
|
|
8
|
+
const workspaceId = embedConfig?.workspaceId.value.trim() || activeOrganization.value?.id?.trim();
|
|
8
9
|
if (workspaceId) {
|
|
9
10
|
mergedHeaders["x-chat-workspace-id"] = workspaceId;
|
|
10
11
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { DeepReadonly } from 'vue';
|
|
2
|
-
import type { Conversation, ModelOption } from '../types/chat.js';
|
|
2
|
+
import type { Conversation, ConversationWithMessages, ModelOption } from '../types/chat.js';
|
|
3
|
+
export declare function mergeFetchedConversations(fetchedConversations: Conversation[], localConversations: readonly Conversation[], deletedConversationIds?: readonly string[], locallyMutatedConversationIds?: readonly string[]): Conversation[];
|
|
3
4
|
export declare function useConversations(): {
|
|
4
5
|
conversations: any;
|
|
5
6
|
loading: any;
|
|
@@ -10,6 +11,6 @@ export declare function useConversations(): {
|
|
|
10
11
|
}) => Promise<Conversation | null>;
|
|
11
12
|
deleteConversation: (id: string) => Promise<boolean>;
|
|
12
13
|
renameConversation: (id: string, title: string) => Promise<boolean>;
|
|
13
|
-
duplicateConversation: (id: string) => Promise<
|
|
14
|
+
duplicateConversation: (id: string) => Promise<ConversationWithMessages | null>;
|
|
14
15
|
updateConversationInList: (updated: Conversation | DeepReadonly<Conversation>) => void;
|
|
15
16
|
};
|