@meistrari/chat-nuxt 1.6.0 → 1.8.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 +25 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +23 -2
- package/dist/runtime/components/MeistrariChatEmbed.vue +8 -1
- package/dist/runtime/components/chat/bash-widget.vue +3 -3
- package/dist/runtime/components/chat/doc-sdk-widget.vue +3 -3
- package/dist/runtime/components/chat/files-view.vue +3 -64
- package/dist/runtime/components/chat/generic-tool-widget.vue +3 -3
- package/dist/runtime/components/chat/grep-widget.vue +3 -3
- package/dist/runtime/components/chat/message-bubble.vue +1 -1
- package/dist/runtime/components/chat/message-input.d.vue.ts +2 -0
- package/dist/runtime/components/chat/message-input.vue +21 -5
- package/dist/runtime/components/chat/message-input.vue.d.ts +2 -0
- package/dist/runtime/components/chat/message-list.vue +1 -1
- package/dist/runtime/components/chat/mobile/files/file-preview.d.vue.ts +11 -0
- package/dist/runtime/components/chat/mobile/files/file-preview.vue +112 -0
- package/dist/runtime/components/chat/mobile/files/file-preview.vue.d.ts +11 -0
- package/dist/runtime/components/chat/mobile/files/files-view.d.vue.ts +10 -0
- package/dist/runtime/components/chat/mobile/files/files-view.vue +384 -0
- package/dist/runtime/components/chat/mobile/files/files-view.vue.d.ts +10 -0
- package/dist/runtime/components/chat/mobile/home/header.d.vue.ts +19 -0
- package/dist/runtime/components/chat/mobile/home/header.vue +55 -0
- package/dist/runtime/components/chat/mobile/home/header.vue.d.ts +19 -0
- package/dist/runtime/components/chat/mobile/home/recents.d.vue.ts +14 -0
- package/dist/runtime/components/chat/mobile/home/recents.vue +48 -0
- package/dist/runtime/components/chat/mobile/home/recents.vue.d.ts +14 -0
- package/dist/runtime/components/chat/mobile/home/suggestions.d.vue.ts +7 -0
- package/dist/runtime/components/chat/mobile/home/suggestions.vue +31 -0
- package/dist/runtime/components/chat/mobile/home/suggestions.vue.d.ts +7 -0
- package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.d.vue.ts +21 -0
- package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.vue +48 -0
- package/dist/runtime/components/chat/mobile/primitives/bottom-sheet.vue.d.ts +21 -0
- package/dist/runtime/components/chat/mobile/primitives/info-bubble.d.vue.ts +6 -0
- package/dist/runtime/components/chat/mobile/primitives/info-bubble.vue +50 -0
- package/dist/runtime/components/chat/mobile/primitives/info-bubble.vue.d.ts +6 -0
- package/dist/runtime/components/chat/mobile/shell/drawer.d.vue.ts +22 -0
- package/dist/runtime/components/chat/mobile/shell/drawer.vue +143 -0
- package/dist/runtime/components/chat/mobile/shell/drawer.vue.d.ts +22 -0
- package/dist/runtime/components/chat/mobile/shell/header.d.vue.ts +40 -0
- package/dist/runtime/components/chat/mobile/shell/header.vue +139 -0
- package/dist/runtime/components/chat/mobile/shell/header.vue.d.ts +40 -0
- package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.d.vue.ts +14 -0
- package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.vue +47 -0
- package/dist/runtime/components/chat/mobile/shell/outdated-settings-sheet.vue.d.ts +14 -0
- package/dist/runtime/components/chat/mobile/shell/shell.d.vue.ts +122 -0
- package/dist/runtime/components/chat/mobile/shell/shell.vue +283 -0
- package/dist/runtime/components/chat/mobile/shell/shell.vue.d.ts +122 -0
- package/dist/runtime/components/chat/mobile/shell/workspace-sheet.d.vue.ts +19 -0
- package/dist/runtime/components/chat/mobile/shell/workspace-sheet.vue +51 -0
- package/dist/runtime/components/chat/mobile/shell/workspace-sheet.vue.d.ts +19 -0
- package/dist/runtime/components/chat/mobile/usage/usage-view.d.vue.ts +8 -0
- package/dist/runtime/components/chat/mobile/usage/usage-view.vue +243 -0
- package/dist/runtime/components/chat/mobile/usage/usage-view.vue.d.ts +8 -0
- package/dist/runtime/components/chat/model-selector.vue +6 -0
- package/dist/runtime/components/chat/read-widget.vue +3 -3
- package/dist/runtime/components/chat/reasoning-step-item.vue +1 -1
- package/dist/runtime/components/chat/reasoning-steps.vue +1 -1
- package/dist/runtime/components/chat/reasoning-thought.vue +2 -3
- package/dist/runtime/components/chat/tela-skill-widget.vue +3 -3
- package/dist/runtime/components/chat/thinking-widget.vue +3 -3
- package/dist/runtime/components/chat/usage-view.vue +20 -101
- package/dist/runtime/components/chat/web-search-widget.vue +3 -3
- package/dist/runtime/components/chat/workstation-query-widget.vue +6 -6
- package/dist/runtime/components/chat/write-widget.vue +3 -3
- package/dist/runtime/composables/useChat.js +2 -1
- package/dist/runtime/composables/useChatApi.js +4 -0
- package/dist/runtime/composables/useConversationFileDownloads.d.ts +6 -0
- package/dist/runtime/composables/useConversationFileDownloads.js +50 -0
- package/dist/runtime/composables/useConversationUsage.d.ts +13 -0
- package/dist/runtime/composables/useConversationUsage.js +121 -0
- package/dist/runtime/composables/useConversations.js +3 -1
- package/dist/runtime/composables/useEmbedConfig.d.ts +4 -0
- package/dist/runtime/composables/useEmbedConfig.js +9 -0
- package/dist/runtime/composables/useMentionAutocomplete.d.ts +6 -0
- package/dist/runtime/composables/useMentionAutocomplete.js +71 -23
- package/dist/runtime/composables/useWorkspaceSwitchModal.d.ts +5 -0
- package/dist/runtime/composables/useWorkspaceSwitchModal.js +14 -0
- package/dist/runtime/embed/components/ChatConfigurationModal.vue +119 -13
- package/dist/runtime/embed/components/ChatEmbed.vue +9 -2
- package/dist/runtime/embed/components/ChatEmbedInner.d.vue.ts +2 -0
- package/dist/runtime/embed/components/ChatEmbedInner.vue +201 -11
- package/dist/runtime/embed/components/ChatEmbedInner.vue.d.ts +2 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.d.vue.ts +34 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.vue +95 -0
- package/dist/runtime/embed/components/configuration/ChatConfigurationMobileShell.vue.d.ts +34 -0
- package/dist/runtime/server/api/conversations/[id]/duplicate.post.js +1 -0
- package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +3 -1
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.js +29 -5
- package/dist/runtime/server/api/conversations/index.post.js +1 -0
- package/dist/runtime/server/db/schema/conversations.d.ts +17 -0
- package/dist/runtime/server/db/schema/conversations.js +1 -0
- package/dist/runtime/server/utils/chat-context.d.ts +2 -0
- package/dist/runtime/server/utils/chat-context.js +15 -1
- package/dist/runtime/server/utils/conversation-message-sync.d.ts +8 -2
- package/dist/runtime/server/utils/conversation-message-sync.js +52 -6
- package/dist/runtime/server/utils/conversation-scope.js +2 -1
- package/dist/runtime/types/chat-auth.d.ts +9 -8
- package/dist/runtime/types/embed.d.ts +21 -0
- package/dist/runtime/utils/breakpoints.d.ts +1 -0
- package/dist/runtime/utils/breakpoints.js +1 -0
- package/dist/runtime/utils/tela-chat.d.ts +3 -1
- package/dist/runtime/utils/tela-chat.js +11 -2
- package/drizzle/0015_illegal_blindfold.sql +1 -0
- package/drizzle/meta/0015_snapshot.json +738 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +6 -1
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversationId?: string | null;
|
|
5
5
|
initialConversationId?: string | null;
|
|
6
6
|
hideSidebar?: boolean;
|
|
7
|
+
hideSettings?: boolean;
|
|
7
8
|
user?: EmbedUser | null;
|
|
8
9
|
features?: Partial<ChatFeatureConfig>;
|
|
9
10
|
};
|
|
@@ -14,6 +15,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
14
15
|
}>, {
|
|
15
16
|
initialConversationId: string | null;
|
|
16
17
|
hideSidebar: boolean;
|
|
18
|
+
hideSettings: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const _default: typeof __VLS_export;
|
|
19
21
|
export default _default;
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { useChatAuth } from "#chat-auth";
|
|
3
|
+
import { useBreakpoints } from "@vueuse/core";
|
|
3
4
|
import { exportConversationToMarkdown } from "../../utils/export-conversation";
|
|
5
|
+
import { CHAT_MOBILE_BREAKPOINT } from "../../utils/breakpoints";
|
|
6
|
+
import ChatMobileFilePreview from "../../components/chat/mobile/files/file-preview.vue";
|
|
7
|
+
import ChatMobileShell from "../../components/chat/mobile/shell/shell.vue";
|
|
4
8
|
import { conversationListSkeletonRows } from "../../utils/conversation-list-skeleton";
|
|
5
9
|
import {
|
|
6
10
|
normalizeConversationId,
|
|
@@ -11,13 +15,15 @@ const props = defineProps({
|
|
|
11
15
|
conversationId: { type: [String, null], required: false },
|
|
12
16
|
initialConversationId: { type: [String, null], required: false, default: null },
|
|
13
17
|
hideSidebar: { type: Boolean, required: false, default: true },
|
|
18
|
+
hideSettings: { type: Boolean, required: false, default: false },
|
|
14
19
|
user: { type: [Object, null], required: false },
|
|
15
20
|
features: { type: Object, required: false }
|
|
16
21
|
});
|
|
17
22
|
const emit = defineEmits(["update:conversationId"]);
|
|
18
23
|
const chatApi = useChatApi();
|
|
19
24
|
const embedConfig = useEmbedConfig();
|
|
20
|
-
const
|
|
25
|
+
const chatAction = useChatAction();
|
|
26
|
+
const { user: authUser, activeOrganization, logout } = useChatAuth();
|
|
21
27
|
const { getMember } = useWorkspaceMembers();
|
|
22
28
|
const statusToast = useStatusToast();
|
|
23
29
|
const { conversations, loading: conversationsLoading, fetchConversations, createConversation, deleteConversation, renameConversation, duplicateConversation, updateConversationInList } = useConversations();
|
|
@@ -35,7 +41,7 @@ const effectiveWorkspaceSettings = computed(() => {
|
|
|
35
41
|
return embedConfig?.workspaceSettings.value !== void 0 ? embedConfig.workspaceSettings.value : workspaceSettingsState.value;
|
|
36
42
|
});
|
|
37
43
|
const { closePanel: closeFilesPanel } = useConversationFilesPanel();
|
|
38
|
-
const { isOpen: isPreviewPanelOpen, panelWidth: previewPanelWidth, closePreview } = useFilePreviewPanel();
|
|
44
|
+
const { isOpen: isPreviewPanelOpen, panelWidth: previewPanelWidth, currentFile: currentPreviewFile, closePreview } = useFilePreviewPanel();
|
|
39
45
|
const activeConversationId = ref(
|
|
40
46
|
normalizeConversationId(props.conversationId) ?? normalizeConversationId(props.initialConversationId)
|
|
41
47
|
);
|
|
@@ -45,6 +51,9 @@ const resolvedFeatures = computed(() => resolveChatFeatures(props.features));
|
|
|
45
51
|
const dropZoneRef = ref(null);
|
|
46
52
|
const activeTab = ref("chat");
|
|
47
53
|
const messageInputRef = ref(null);
|
|
54
|
+
const breakpoints = useBreakpoints({ mobile: CHAT_MOBILE_BREAKPOINT });
|
|
55
|
+
const isMobile = breakpoints.smaller("mobile");
|
|
56
|
+
const drawerOpen = ref(false);
|
|
48
57
|
const { isDragging, setupDropZone } = useFileDrop({
|
|
49
58
|
onDrop: (files) => {
|
|
50
59
|
messageInputRef.value?.addFiles(files);
|
|
@@ -79,6 +88,19 @@ const conversationIdRef = computed(() => currentConversation.value?.id ?? null);
|
|
|
79
88
|
const { total, files: conversationFiles } = useConversationFiles(conversationIdRef);
|
|
80
89
|
const filesCount = computed(() => total.value);
|
|
81
90
|
const hasMessages = computed(() => messages.value.length > 0);
|
|
91
|
+
const mobilePreviewFile = computed(() => {
|
|
92
|
+
if (!isPreviewPanelOpen.value || !currentPreviewFile.value)
|
|
93
|
+
return null;
|
|
94
|
+
const file = currentPreviewFile.value;
|
|
95
|
+
return {
|
|
96
|
+
id: file.file.reference,
|
|
97
|
+
url: file.resolvedUrl ?? file.file.reference,
|
|
98
|
+
name: file.file.hashParams?.filename ?? file.originalFileName ?? file.file.name,
|
|
99
|
+
mimeType: file.resolvedMimeType ?? file.file.mimeType,
|
|
100
|
+
source: "message",
|
|
101
|
+
size: file.fileSize
|
|
102
|
+
};
|
|
103
|
+
});
|
|
82
104
|
const visibleTelaAgentInputSchema = computed(() => !hasMessages.value ? telaAgentInputSchema.value : null);
|
|
83
105
|
const visibleTelaAgentInputSchemaLoading = computed(() => !hasMessages.value && shouldLoadTelaAgentMetadata.value && telaAgentMetadataLoading.value);
|
|
84
106
|
const visibleConversations = computed(
|
|
@@ -268,6 +290,33 @@ async function handleRetry(messageId) {
|
|
|
268
290
|
async function handleNewConversation() {
|
|
269
291
|
resetConversation();
|
|
270
292
|
}
|
|
293
|
+
const workspaceSheetOpen = ref(false);
|
|
294
|
+
const {
|
|
295
|
+
settings: workspaceSettingsForModal,
|
|
296
|
+
fetchSettings: fetchWorkspaceSettingsForModal,
|
|
297
|
+
openModal: openWorkspaceSettingsModal
|
|
298
|
+
} = useWorkspaceSettings();
|
|
299
|
+
const { openModal: openWorkspaceSwitchModal } = useWorkspaceSwitchModal();
|
|
300
|
+
async function handleOpenWorkspaceSettings() {
|
|
301
|
+
if (!workspaceSettingsForModal.value) {
|
|
302
|
+
try {
|
|
303
|
+
await fetchWorkspaceSettingsForModal();
|
|
304
|
+
} catch (err) {
|
|
305
|
+
console.error("Failed to load workspace settings:", err);
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
openWorkspaceSettingsModal();
|
|
310
|
+
}
|
|
311
|
+
function handleSwitchWorkspace() {
|
|
312
|
+
openWorkspaceSwitchModal();
|
|
313
|
+
}
|
|
314
|
+
async function handleSignout() {
|
|
315
|
+
chatAction.emit("signout");
|
|
316
|
+
await logout();
|
|
317
|
+
}
|
|
318
|
+
const workspaceName = computed(() => activeOrganization.value?.name ?? "Workspace");
|
|
319
|
+
const workspaceLogo = computed(() => activeOrganization.value?.logo ?? void 0);
|
|
271
320
|
function handleTabChange(tab) {
|
|
272
321
|
activeTab.value = tab;
|
|
273
322
|
if (tab === "chat")
|
|
@@ -355,7 +404,7 @@ async function handleDelete() {
|
|
|
355
404
|
<div ref="dropZoneRef" h-full flex bg-white relative>
|
|
356
405
|
<!-- Sidebar -->
|
|
357
406
|
<div
|
|
358
|
-
v-if="!hideSidebar"
|
|
407
|
+
v-if="!hideSidebar && !isMobile"
|
|
359
408
|
w-240px h-full flex="~ col" flex-shrink-0
|
|
360
409
|
bg-neutral-50 b-r=".5px neutral-200"
|
|
361
410
|
>
|
|
@@ -408,8 +457,143 @@ async function handleDelete() {
|
|
|
408
457
|
<div flex-1 h-full flex="~ col" overflow-hidden relative style="--chat-panel-offset: 0px">
|
|
409
458
|
<div v-if="loading && currentConversation" class="loading-bar" />
|
|
410
459
|
|
|
460
|
+
<ChatMobileShell
|
|
461
|
+
v-if="isMobile"
|
|
462
|
+
v-model:drawer-open="drawerOpen"
|
|
463
|
+
v-model:edit-title="editTitle"
|
|
464
|
+
v-model:model="selectedModel"
|
|
465
|
+
v-model:workspace-sheet-open="workspaceSheetOpen"
|
|
466
|
+
:current-conversation="currentConversation"
|
|
467
|
+
:display-title="displayTitle"
|
|
468
|
+
:conversation-creator="conversationCreator"
|
|
469
|
+
:current-user="currentUser"
|
|
470
|
+
:active-tab="activeTab"
|
|
471
|
+
:active-conversation-id="activeConversationId"
|
|
472
|
+
:conversations="visibleConversations"
|
|
473
|
+
:conversations-loading="conversationsLoading"
|
|
474
|
+
:conversation-files="conversationFiles"
|
|
475
|
+
:files-count="filesCount"
|
|
476
|
+
:generating-title="generatingTitle"
|
|
477
|
+
:has-messages="hasMessages"
|
|
478
|
+
:has-pending-message="hasPendingMessage"
|
|
479
|
+
:hide-settings="hideSettings"
|
|
480
|
+
:hide-sidebar="hideSidebar"
|
|
481
|
+
:is-editing="isEditing"
|
|
482
|
+
:loading="loading"
|
|
483
|
+
:messages="messages"
|
|
484
|
+
:allow-model-selection="!isTelaAgentMode"
|
|
485
|
+
:agent-input-schema="visibleTelaAgentInputSchema"
|
|
486
|
+
:agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
|
|
487
|
+
:show-model-selector="resolvedFeatures.showModelSelector"
|
|
488
|
+
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
489
|
+
:show-debug-option="resolvedFeatures.showDebugOption"
|
|
490
|
+
:show-outdated-badge="showOutdatedBadge"
|
|
491
|
+
:show-outdated-banner="showOutdatedBanner"
|
|
492
|
+
:show-usage-tab="resolvedFeatures.showUsageTab"
|
|
493
|
+
:workspace-logo="workspaceLogo"
|
|
494
|
+
:workspace-name="workspaceName"
|
|
495
|
+
:workspace-settings="effectiveWorkspaceSettings"
|
|
496
|
+
@cancel="cancelConversation"
|
|
497
|
+
@cancel-editing="cancelEditing"
|
|
498
|
+
@copy-link="handleShare"
|
|
499
|
+
@debug="showDebugModal = true"
|
|
500
|
+
@delete="showDeleteModal = true"
|
|
501
|
+
@dismiss-outdated-banner="dismissOutdatedBanner"
|
|
502
|
+
@duplicate="handleDuplicate"
|
|
503
|
+
@export="handleExport"
|
|
504
|
+
@new-conversation="handleNewConversation"
|
|
505
|
+
@rename="startEditing"
|
|
506
|
+
@save-title="saveTitle"
|
|
507
|
+
@select-conversation="openConversation"
|
|
508
|
+
@send="handleSend"
|
|
509
|
+
@settings="handleOpenWorkspaceSettings"
|
|
510
|
+
@signout="handleSignout"
|
|
511
|
+
@switch-workspace="handleSwitchWorkspace"
|
|
512
|
+
@tab-change="handleTabChange"
|
|
513
|
+
>
|
|
514
|
+
<template #loading>
|
|
515
|
+
<ChatMessageList
|
|
516
|
+
:messages="[]"
|
|
517
|
+
loading
|
|
518
|
+
/>
|
|
519
|
+
<ChatMessageInput
|
|
520
|
+
v-model:model="selectedModel"
|
|
521
|
+
:disabled="true"
|
|
522
|
+
:allow-model-selection="!isTelaAgentMode"
|
|
523
|
+
:agent-input-schema="visibleTelaAgentInputSchema"
|
|
524
|
+
:agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
|
|
525
|
+
:show-model-selector="resolvedFeatures.showModelSelector"
|
|
526
|
+
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
527
|
+
/>
|
|
528
|
+
</template>
|
|
529
|
+
|
|
530
|
+
<template #empty>
|
|
531
|
+
<div
|
|
532
|
+
flex-1 flex="~ col" items-center justify-center gap-40px px-24px
|
|
533
|
+
:class="currentConversation ? 'pt-64px' : ''"
|
|
534
|
+
>
|
|
535
|
+
<div flex="~ col" items-center gap-8px text-center>
|
|
536
|
+
<h1 text-24px font-semibold text-gray-800 leading-28px tracking="-.8px">
|
|
537
|
+
Olá, {{ currentUser?.name?.split(" ")[0] ?? "usu\xE1rio" }}
|
|
538
|
+
</h1>
|
|
539
|
+
<p text-16px text-gray-500 leading-20px tracking="-.2px">
|
|
540
|
+
Como posso te ajudar hoje?
|
|
541
|
+
</p>
|
|
542
|
+
</div>
|
|
543
|
+
<ChatMessageInput
|
|
544
|
+
ref="messageInputRef"
|
|
545
|
+
v-model:model="selectedModel"
|
|
546
|
+
:disabled="hasPendingMessage"
|
|
547
|
+
:loading="hasPendingMessage"
|
|
548
|
+
:creator-name="currentUser?.name ?? void 0"
|
|
549
|
+
:creator-email="currentConversation?.createdBy ?? currentUser?.email ?? void 0"
|
|
550
|
+
:creator-image="currentUser?.image ?? void 0"
|
|
551
|
+
:messages="messages"
|
|
552
|
+
:conversation-files="conversationFiles"
|
|
553
|
+
:workspace-settings="effectiveWorkspaceSettings"
|
|
554
|
+
:allow-model-selection="!isTelaAgentMode"
|
|
555
|
+
:agent-input-schema="visibleTelaAgentInputSchema"
|
|
556
|
+
:agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
|
|
557
|
+
:show-model-selector="resolvedFeatures.showModelSelector"
|
|
558
|
+
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
559
|
+
centered
|
|
560
|
+
@send="handleSend"
|
|
561
|
+
@cancel="cancelConversation"
|
|
562
|
+
/>
|
|
563
|
+
</div>
|
|
564
|
+
</template>
|
|
565
|
+
|
|
566
|
+
<ChatMessageList
|
|
567
|
+
:messages="messages"
|
|
568
|
+
@retry="handleRetry"
|
|
569
|
+
/>
|
|
570
|
+
<ChatMessageInput
|
|
571
|
+
ref="messageInputRef"
|
|
572
|
+
v-model:model="selectedModel"
|
|
573
|
+
:disabled="hasPendingMessage"
|
|
574
|
+
:loading="hasPendingMessage"
|
|
575
|
+
:creator-name="currentUser?.name ?? void 0"
|
|
576
|
+
:creator-email="currentConversation?.createdBy ?? currentUser?.email ?? void 0"
|
|
577
|
+
:creator-image="currentUser?.image ?? void 0"
|
|
578
|
+
:messages="messages"
|
|
579
|
+
:conversation-files="conversationFiles"
|
|
580
|
+
:workspace-settings="effectiveWorkspaceSettings"
|
|
581
|
+
:allow-model-selection="!isTelaAgentMode"
|
|
582
|
+
:agent-input-schema="visibleTelaAgentInputSchema"
|
|
583
|
+
:agent-input-schema-loading="visibleTelaAgentInputSchemaLoading"
|
|
584
|
+
:show-model-selector="resolvedFeatures.showModelSelector"
|
|
585
|
+
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
586
|
+
has-disclaimer
|
|
587
|
+
@send="handleSend"
|
|
588
|
+
@cancel="cancelConversation"
|
|
589
|
+
/>
|
|
590
|
+
<p text-center text-12px font-400 leading-16px text-tertiary my-8px>
|
|
591
|
+
As respostas podem conter erros. Verifique documentos originais.
|
|
592
|
+
</p>
|
|
593
|
+
</ChatMobileShell>
|
|
594
|
+
|
|
411
595
|
<ChatTopbar
|
|
412
|
-
v-if="currentConversation"
|
|
596
|
+
v-if="currentConversation && !isMobile"
|
|
413
597
|
:title="displayTitle"
|
|
414
598
|
:creator-name="conversationCreator?.name ?? void 0"
|
|
415
599
|
:creator-email="currentConversation.createdBy ?? void 0"
|
|
@@ -437,7 +621,7 @@ async function handleDelete() {
|
|
|
437
621
|
/>
|
|
438
622
|
|
|
439
623
|
<div
|
|
440
|
-
v-if="showOutdatedBanner"
|
|
624
|
+
v-if="!isMobile && showOutdatedBanner"
|
|
441
625
|
mt-64px flex items-center h-36px px-12px bg="#FFF1D8"
|
|
442
626
|
>
|
|
443
627
|
<div flex items-center gap-8px flex-1>
|
|
@@ -469,11 +653,11 @@ async function handleDelete() {
|
|
|
469
653
|
</div>
|
|
470
654
|
</div>
|
|
471
655
|
|
|
472
|
-
<template v-if="activeTab === 'files' && currentConversation">
|
|
656
|
+
<template v-if="!isMobile && activeTab === 'files' && currentConversation">
|
|
473
657
|
<ChatFilesView :conversation-id="currentConversation.id" />
|
|
474
658
|
</template>
|
|
475
659
|
|
|
476
|
-
<template v-else-if="activeTab === 'usage' && resolvedFeatures.showUsageTab && currentConversation">
|
|
660
|
+
<template v-else-if="!isMobile && activeTab === 'usage' && resolvedFeatures.showUsageTab && currentConversation">
|
|
477
661
|
<ChatUsageView
|
|
478
662
|
:conversation-id="currentConversation.id"
|
|
479
663
|
:created-at="currentConversation.createdAt"
|
|
@@ -481,7 +665,7 @@ async function handleDelete() {
|
|
|
481
665
|
/>
|
|
482
666
|
</template>
|
|
483
667
|
|
|
484
|
-
<template v-else-if="loading">
|
|
668
|
+
<template v-else-if="!isMobile && loading">
|
|
485
669
|
<ChatMessageList
|
|
486
670
|
:messages="[]"
|
|
487
671
|
loading
|
|
@@ -497,7 +681,7 @@ async function handleDelete() {
|
|
|
497
681
|
/>
|
|
498
682
|
</template>
|
|
499
683
|
|
|
500
|
-
<template v-else-if="!hasMessages">
|
|
684
|
+
<template v-else-if="!isMobile && !hasMessages">
|
|
501
685
|
<div
|
|
502
686
|
flex-1 flex="~ col" items-center justify-center gap-40px px-24px
|
|
503
687
|
:class="currentConversation ? 'pt-64px' : ''"
|
|
@@ -533,7 +717,7 @@ async function handleDelete() {
|
|
|
533
717
|
</div>
|
|
534
718
|
</template>
|
|
535
719
|
|
|
536
|
-
<template v-else>
|
|
720
|
+
<template v-else-if="!isMobile">
|
|
537
721
|
<ChatMessageList
|
|
538
722
|
:messages="messages"
|
|
539
723
|
@retry="handleRetry"
|
|
@@ -648,8 +832,14 @@ async function handleDelete() {
|
|
|
648
832
|
</TelaModal>
|
|
649
833
|
</div>
|
|
650
834
|
|
|
835
|
+
<ChatMobileFilePreview
|
|
836
|
+
v-if="isPreviewPanelOpen && isMobile"
|
|
837
|
+
:file="mobilePreviewFile"
|
|
838
|
+
@close="closePreview"
|
|
839
|
+
/>
|
|
840
|
+
|
|
651
841
|
<div
|
|
652
|
-
v-if="isPreviewPanelOpen"
|
|
842
|
+
v-if="isPreviewPanelOpen && !isMobile"
|
|
653
843
|
h-full flex-shrink-0 pt-64px
|
|
654
844
|
:style="{ width: `${previewPanelWidth}px` }"
|
|
655
845
|
>
|
|
@@ -4,6 +4,7 @@ type __VLS_Props = {
|
|
|
4
4
|
conversationId?: string | null;
|
|
5
5
|
initialConversationId?: string | null;
|
|
6
6
|
hideSidebar?: boolean;
|
|
7
|
+
hideSettings?: boolean;
|
|
7
8
|
user?: EmbedUser | null;
|
|
8
9
|
features?: Partial<ChatFeatureConfig>;
|
|
9
10
|
};
|
|
@@ -14,6 +15,7 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
14
15
|
}>, {
|
|
15
16
|
initialConversationId: string | null;
|
|
16
17
|
hideSidebar: boolean;
|
|
18
|
+
hideSettings: boolean;
|
|
17
19
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
18
20
|
declare const _default: typeof __VLS_export;
|
|
19
21
|
export default _default;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type SettingsTab = {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
icon: string;
|
|
5
|
+
};
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
tabs: SettingsTab[];
|
|
8
|
+
activeTab: string | null;
|
|
9
|
+
hasChanges?: boolean;
|
|
10
|
+
isBusy?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare var __VLS_19: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_19) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
|
+
close: () => any;
|
|
18
|
+
save: () => any;
|
|
19
|
+
back: () => any;
|
|
20
|
+
selectTab: (value: string) => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
22
|
+
onClose?: (() => any) | undefined;
|
|
23
|
+
onSave?: (() => any) | undefined;
|
|
24
|
+
onBack?: (() => any) | undefined;
|
|
25
|
+
onSelectTab?: ((value: string) => any) | undefined;
|
|
26
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
31
|
+
new (): {
|
|
32
|
+
$slots: S;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
tabs: { type: Array, required: true },
|
|
4
|
+
activeTab: { type: [String, null], required: true },
|
|
5
|
+
hasChanges: { type: Boolean, required: false },
|
|
6
|
+
isBusy: { type: Boolean, required: false }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["back", "close", "save", "selectTab"]);
|
|
9
|
+
const transitionName = ref("mobile-config-slide-forward");
|
|
10
|
+
const activeTabLabel = computed(() => props.tabs.find((tab) => tab.value === props.activeTab)?.label ?? "Configura\xE7\xF5es");
|
|
11
|
+
watch(() => props.activeTab, (activeTab, previousActiveTab) => {
|
|
12
|
+
if (activeTab && !previousActiveTab)
|
|
13
|
+
transitionName.value = "mobile-config-slide-forward";
|
|
14
|
+
else if (!activeTab && previousActiveTab)
|
|
15
|
+
transitionName.value = "mobile-config-slide-back";
|
|
16
|
+
else
|
|
17
|
+
transitionName.value = "mobile-config-fade";
|
|
18
|
+
});
|
|
19
|
+
</script>
|
|
20
|
+
|
|
21
|
+
<template>
|
|
22
|
+
<div class="mobile-config" role="dialog" aria-modal="true">
|
|
23
|
+
<header class="mobile-config__header">
|
|
24
|
+
<Transition name="mobile-config-fade" mode="out-in">
|
|
25
|
+
<button
|
|
26
|
+
v-if="activeTab"
|
|
27
|
+
key="back"
|
|
28
|
+
type="button"
|
|
29
|
+
class="mobile-config__icon-btn"
|
|
30
|
+
aria-label="Voltar"
|
|
31
|
+
@click="emit('back')"
|
|
32
|
+
>
|
|
33
|
+
<span i-ph-arrow-left text-20px />
|
|
34
|
+
</button>
|
|
35
|
+
<div v-else key="spacer" class="mobile-config__header-spacer" />
|
|
36
|
+
</Transition>
|
|
37
|
+
|
|
38
|
+
<Transition name="mobile-config-title" mode="out-in">
|
|
39
|
+
<h1 :key="activeTab ?? 'settings-list'">
|
|
40
|
+
{{ activeTab ? activeTabLabel : "Configura\xE7\xF5es" }}
|
|
41
|
+
</h1>
|
|
42
|
+
</Transition>
|
|
43
|
+
|
|
44
|
+
<button
|
|
45
|
+
type="button"
|
|
46
|
+
class="mobile-config__icon-btn"
|
|
47
|
+
aria-label="Fechar configurações"
|
|
48
|
+
@click="emit('close')"
|
|
49
|
+
>
|
|
50
|
+
<span i-ph-x text-20px />
|
|
51
|
+
</button>
|
|
52
|
+
</header>
|
|
53
|
+
|
|
54
|
+
<Transition :name="transitionName" mode="out-in">
|
|
55
|
+
<main v-if="!activeTab" key="settings-list" class="mobile-config__list">
|
|
56
|
+
<button
|
|
57
|
+
v-for="tab in tabs"
|
|
58
|
+
:key="tab.value"
|
|
59
|
+
type="button"
|
|
60
|
+
class="mobile-config__list-item"
|
|
61
|
+
@click="emit('selectTab', tab.value)"
|
|
62
|
+
>
|
|
63
|
+
<span :class="tab.icon" class="mobile-config__list-icon" />
|
|
64
|
+
<span>{{ tab.label }}</span>
|
|
65
|
+
<span i-ph-caret-right text-18px text-neutral-400 />
|
|
66
|
+
</button>
|
|
67
|
+
</main>
|
|
68
|
+
|
|
69
|
+
<main v-else :key="activeTab" class="mobile-config__detail">
|
|
70
|
+
<div class="mobile-config__content">
|
|
71
|
+
<slot />
|
|
72
|
+
</div>
|
|
73
|
+
|
|
74
|
+
<footer class="mobile-config__footer">
|
|
75
|
+
<TelaButton
|
|
76
|
+
size="lg"
|
|
77
|
+
class="mobile-config__save"
|
|
78
|
+
:disabled="!hasChanges || isBusy"
|
|
79
|
+
@click="emit('save')"
|
|
80
|
+
>
|
|
81
|
+
<span v-if="isBusy" flex items-center gap-6px>
|
|
82
|
+
<div i-ph-spinner animate-spin />
|
|
83
|
+
Salvando...
|
|
84
|
+
</span>
|
|
85
|
+
<span v-else>Salvar</span>
|
|
86
|
+
</TelaButton>
|
|
87
|
+
</footer>
|
|
88
|
+
</main>
|
|
89
|
+
</Transition>
|
|
90
|
+
</div>
|
|
91
|
+
</template>
|
|
92
|
+
|
|
93
|
+
<style scoped>
|
|
94
|
+
.mobile-config{background:#fff;display:flex;flex-direction:column;inset:0;position:fixed;z-index:550}.mobile-config__header{align-items:center;background:#fff;border-bottom:.5px solid rgba(0,0,0,.08);display:grid;flex-shrink:0;grid-template-columns:44px 1fr 44px;min-height:56px;padding:6px 10px}.mobile-config__header h1{color:#171717;font-size:16px;font-weight:580;line-height:20px;margin:0;overflow:hidden;text-align:center;text-overflow:ellipsis;white-space:nowrap}.mobile-config__header-spacer{height:44px;width:44px}.mobile-config__icon-btn{align-items:center;background:transparent;border-radius:12px;color:#171717;display:inline-flex;height:44px;justify-content:center;transition:background .15s,transform .12s;width:44px}.mobile-config__icon-btn:active{background:#f5f5f5;transform:scale(.96)}.mobile-config__list{background:#f7f7f7;flex:1;overflow-y:auto;padding:12px 12px max(20px,env(safe-area-inset-bottom))}.mobile-config__list-item{align-items:center;background:#fff;border-bottom:.5px solid #f0f0f0;color:#171717;display:grid;gap:12px;grid-template-columns:24px 1fr 20px;min-height:52px;padding:12px 14px;text-align:left;width:100%}.mobile-config__list-item:first-child{border-radius:14px 14px 0 0}.mobile-config__list-item:last-child{border-bottom:0;border-radius:0 0 14px 14px}.mobile-config__list-item:only-child{border-radius:14px}.mobile-config__list-item:active{background:#f5f5f5}.mobile-config__list-icon{color:#6b7280;font-size:20px}.mobile-config__list-item span:nth-child(2){font-size:15px;font-weight:500;line-height:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mobile-config__detail{display:flex;flex:1;flex-direction:column;min-height:0}.mobile-config__content{flex:1;min-height:0;overflow-y:auto;padding:20px 18px 24px}.mobile-config__footer{background:#fff;border-top:.5px solid rgba(0,0,0,.08);flex-shrink:0;padding:12px 18px max(18px,env(safe-area-inset-bottom))}.mobile-config__save{width:100%}.mobile-config-fade-enter-active,.mobile-config-fade-leave-active,.mobile-config-slide-back-enter-active,.mobile-config-slide-back-leave-active,.mobile-config-slide-forward-enter-active,.mobile-config-slide-forward-leave-active,.mobile-config-title-enter-active,.mobile-config-title-leave-active{transition:opacity .18s cubic-bezier(.22,1,.36,1),transform .18s cubic-bezier(.22,1,.36,1)}.mobile-config-slide-back-enter-active,.mobile-config-slide-back-leave-active,.mobile-config-slide-forward-enter-active,.mobile-config-slide-forward-leave-active{will-change:opacity,transform}.mobile-config-slide-forward-enter-from{opacity:0;transform:translateX(18px)}.mobile-config-slide-back-enter-from,.mobile-config-slide-forward-leave-to{opacity:0;transform:translateX(-18px)}.mobile-config-slide-back-leave-to{opacity:0;transform:translateX(18px)}.mobile-config-fade-enter-from,.mobile-config-fade-leave-to,.mobile-config-title-enter-from,.mobile-config-title-leave-to{opacity:0}.mobile-config-title-enter-from{transform:translateY(3px)}.mobile-config-title-leave-to{transform:translateY(-3px)}@media (prefers-reduced-motion:reduce){.mobile-config-fade-enter-active,.mobile-config-fade-leave-active,.mobile-config-slide-back-enter-active,.mobile-config-slide-back-leave-active,.mobile-config-slide-forward-enter-active,.mobile-config-slide-forward-leave-active,.mobile-config-title-enter-active,.mobile-config-title-leave-active{transition-duration:1ms}.mobile-config-slide-back-enter-from,.mobile-config-slide-back-leave-to,.mobile-config-slide-forward-enter-from,.mobile-config-slide-forward-leave-to,.mobile-config-title-enter-from,.mobile-config-title-leave-to{transform:none}}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
type SettingsTab = {
|
|
2
|
+
value: string;
|
|
3
|
+
label: string;
|
|
4
|
+
icon: string;
|
|
5
|
+
};
|
|
6
|
+
type __VLS_Props = {
|
|
7
|
+
tabs: SettingsTab[];
|
|
8
|
+
activeTab: string | null;
|
|
9
|
+
hasChanges?: boolean;
|
|
10
|
+
isBusy?: boolean;
|
|
11
|
+
};
|
|
12
|
+
declare var __VLS_19: {};
|
|
13
|
+
type __VLS_Slots = {} & {
|
|
14
|
+
default?: (props: typeof __VLS_19) => any;
|
|
15
|
+
};
|
|
16
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
|
+
close: () => any;
|
|
18
|
+
save: () => any;
|
|
19
|
+
back: () => any;
|
|
20
|
+
selectTab: (value: string) => any;
|
|
21
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
22
|
+
onClose?: (() => any) | undefined;
|
|
23
|
+
onSave?: (() => any) | undefined;
|
|
24
|
+
onBack?: (() => any) | undefined;
|
|
25
|
+
onSelectTab?: ((value: string) => any) | undefined;
|
|
26
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
27
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
28
|
+
declare const _default: typeof __VLS_export;
|
|
29
|
+
export default _default;
|
|
30
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
31
|
+
new (): {
|
|
32
|
+
$slots: S;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
@@ -30,6 +30,7 @@ export default defineEventHandler(async (event) => {
|
|
|
30
30
|
title: `${original.title} (copy)`,
|
|
31
31
|
createdBy: context.user.email,
|
|
32
32
|
telaAgentId: original.telaAgentId,
|
|
33
|
+
conversationScope: original.conversationScope,
|
|
33
34
|
threadSessionId: null,
|
|
34
35
|
model: original.telaAgentId ? null : original.model,
|
|
35
36
|
appliedSettingsAt: trustedSettings ? getWorkspaceSettingsUpdatedAt(trustedSettings) : null,
|
|
@@ -62,7 +62,9 @@ export default defineEventHandler(async (event) => {
|
|
|
62
62
|
content: "",
|
|
63
63
|
status: "pending",
|
|
64
64
|
reasoningData: null,
|
|
65
|
-
files: null
|
|
65
|
+
files: null,
|
|
66
|
+
ttft: null,
|
|
67
|
+
updatedAt: null
|
|
66
68
|
}).where(eq(schema.messages.id, messageId));
|
|
67
69
|
logger.info({ conversationId, messageId }, "Message retry initiated");
|
|
68
70
|
if (conversation.telaAgentId) {
|
|
@@ -5,10 +5,14 @@ import { getAgentDataToken, getSessionStatus } from "#chat-runtime/server/utils/
|
|
|
5
5
|
import { resolveChatRuntimeContext } from "#chat-runtime/server/utils/chat-context";
|
|
6
6
|
import { attachNewAssistantFilesToMessageUpdate } from "#chat-runtime/server/utils/conversation-message-files";
|
|
7
7
|
import {
|
|
8
|
+
buildFailedPendingMessageUpdate,
|
|
8
9
|
buildMessageUpdateResponse,
|
|
9
10
|
hasMessageUpdate,
|
|
11
|
+
hasPendingMessageExceededGraceWindow,
|
|
10
12
|
isTerminalMessageUpdate,
|
|
11
13
|
mapAgentApiSessionToMessageUpdate,
|
|
14
|
+
SESSION_STATUS_CHECK_ERROR,
|
|
15
|
+
THREAD_SESSION_START_ERROR,
|
|
12
16
|
trackAgentApiConversationUsage,
|
|
13
17
|
trackTelaAgentConversationUsage
|
|
14
18
|
} from "#chat-runtime/server/utils/conversation-message-sync";
|
|
@@ -48,10 +52,22 @@ export default defineEventHandler(async (event) => {
|
|
|
48
52
|
});
|
|
49
53
|
}
|
|
50
54
|
const pendingMessage = messages.find((message) => message.status === "pending");
|
|
51
|
-
const
|
|
52
|
-
|
|
55
|
+
const lastCompletedAssistantMessage = messages.findLast((message) => message.role === "assistant" && message.status === "completed");
|
|
56
|
+
const lastTerminalAssistantMessage = messages.findLast(
|
|
57
|
+
(message) => message.role === "assistant" && (message.status === "completed" || message.status === "failed")
|
|
58
|
+
);
|
|
59
|
+
if (!pendingMessage) {
|
|
53
60
|
return { messages };
|
|
54
61
|
}
|
|
62
|
+
if (!conversation.threadSessionId) {
|
|
63
|
+
if (!hasPendingMessageExceededGraceWindow(pendingMessage)) {
|
|
64
|
+
return { messages };
|
|
65
|
+
}
|
|
66
|
+
const updateData2 = buildFailedPendingMessageUpdate(THREAD_SESSION_START_ERROR);
|
|
67
|
+
logger.warn({ conversationId, messageId: pendingMessage.id }, "Pending message failed because thread session was not created");
|
|
68
|
+
await db.update(schema.messages).set(updateData2).where(eq(schema.messages.id, pendingMessage.id));
|
|
69
|
+
return buildMessageUpdateResponse(messages, pendingMessage.id, updateData2);
|
|
70
|
+
}
|
|
55
71
|
logger.debug({ conversationId, messageId: pendingMessage.id, sessionId: conversation.threadSessionId }, "Polling pending message");
|
|
56
72
|
if (conversation.telaAgentId) {
|
|
57
73
|
const sessionResult2 = await getTelaAgentSession(event, conversation.threadSessionId);
|
|
@@ -61,7 +77,7 @@ export default defineEventHandler(async (event) => {
|
|
|
61
77
|
const agentSession2 = sessionResult2.data;
|
|
62
78
|
const userMessage2 = messages.findLast((message) => message.role === "user");
|
|
63
79
|
const updateData2 = mapTelaAgentSessionToMessageUpdate(agentSession2, {
|
|
64
|
-
lastSyncedStepId: pendingMessage.externalUuid ??
|
|
80
|
+
lastSyncedStepId: pendingMessage.externalUuid ?? lastTerminalAssistantMessage?.externalUuid,
|
|
65
81
|
existingReasoningData: Array.isArray(pendingMessage.reasoningData) ? pendingMessage.reasoningData : null,
|
|
66
82
|
pendingMessageTtft: pendingMessage.ttft,
|
|
67
83
|
userMessageCreatedAt: userMessage2?.createdAt ?? null
|
|
@@ -84,13 +100,21 @@ export default defineEventHandler(async (event) => {
|
|
|
84
100
|
}
|
|
85
101
|
const sessionResult = await getSessionStatus(token, conversation.threadSessionId);
|
|
86
102
|
if (!sessionResult.success) {
|
|
87
|
-
|
|
103
|
+
if (!hasPendingMessageExceededGraceWindow(pendingMessage)) {
|
|
104
|
+
logger.debug({ conversationId, messageId: pendingMessage.id, sessionId: conversation.threadSessionId, error: sessionResult.error }, "Agent session status check failed within grace window");
|
|
105
|
+
return { messages };
|
|
106
|
+
}
|
|
107
|
+
const updateData2 = buildFailedPendingMessageUpdate(SESSION_STATUS_CHECK_ERROR);
|
|
108
|
+
logger.warn({ conversationId, messageId: pendingMessage.id, sessionId: conversation.threadSessionId, error: sessionResult.error }, "Pending message failed because session status check did not recover");
|
|
109
|
+
await db.update(schema.messages).set(updateData2).where(eq(schema.messages.id, pendingMessage.id));
|
|
110
|
+
return buildMessageUpdateResponse(messages, pendingMessage.id, updateData2);
|
|
88
111
|
}
|
|
89
112
|
const agentSession = sessionResult.data;
|
|
90
113
|
const userMessage = messages.findLast((message) => message.role === "user");
|
|
91
114
|
const updateData = mapAgentApiSessionToMessageUpdate(agentSession, {
|
|
92
115
|
pendingMessage,
|
|
93
|
-
lastAssistantMessage,
|
|
116
|
+
lastAssistantMessage: lastCompletedAssistantMessage,
|
|
117
|
+
lastSyncedMessage: pendingMessage.externalUuid ? pendingMessage : lastTerminalAssistantMessage,
|
|
94
118
|
userMessage
|
|
95
119
|
});
|
|
96
120
|
if (updateData.status === "completed") {
|
|
@@ -30,6 +30,7 @@ export default defineEventHandler(async (event) => {
|
|
|
30
30
|
userId: context.user.id,
|
|
31
31
|
createdBy: context.user.email,
|
|
32
32
|
telaAgentId: context.telaAgentId,
|
|
33
|
+
conversationScope: context.conversationScope,
|
|
33
34
|
...context.telaAgentId ? { model: null } : body.model ? { model: body.model } : {}
|
|
34
35
|
}).returning();
|
|
35
36
|
if (!conversation) {
|
|
@@ -105,6 +105,23 @@ export declare const conversations: import("drizzle-orm/pg-core").PgTableWithCol
|
|
|
105
105
|
identity: undefined;
|
|
106
106
|
generated: undefined;
|
|
107
107
|
}, {}, {}>;
|
|
108
|
+
conversationScope: import("drizzle-orm/pg-core").PgColumn<{
|
|
109
|
+
name: "conversation_scope";
|
|
110
|
+
tableName: "conversations";
|
|
111
|
+
dataType: "string";
|
|
112
|
+
columnType: "PgText";
|
|
113
|
+
data: string;
|
|
114
|
+
driverParam: string;
|
|
115
|
+
notNull: false;
|
|
116
|
+
hasDefault: false;
|
|
117
|
+
isPrimaryKey: false;
|
|
118
|
+
isAutoincrement: false;
|
|
119
|
+
hasRuntimeDefault: false;
|
|
120
|
+
enumValues: [string, ...string[]];
|
|
121
|
+
baseColumn: never;
|
|
122
|
+
identity: undefined;
|
|
123
|
+
generated: undefined;
|
|
124
|
+
}, {}, {}>;
|
|
108
125
|
model: import("drizzle-orm/pg-core").PgColumn<{
|
|
109
126
|
name: "model";
|
|
110
127
|
tableName: "conversations";
|
|
@@ -7,6 +7,7 @@ export const conversations = chatSchema.table("conversations", {
|
|
|
7
7
|
title: text("title").notNull().default("Nova conversa"),
|
|
8
8
|
threadSessionId: text("thread_session_id"),
|
|
9
9
|
telaAgentId: text("tela_agent_id"),
|
|
10
|
+
conversationScope: text("conversation_scope"),
|
|
10
11
|
model: text("model").default("claude-sonnet-4-5"),
|
|
11
12
|
appliedSettingsAt: timestamp("applied_settings_at", { withTimezone: true }),
|
|
12
13
|
appliedSettingsSnapshot: jsonb("applied_settings_snapshot").$type(),
|