@meistrari/chat-nuxt 4.2.0-rc.1 → 4.2.0-rc.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 +2 -0
- package/dist/module.json +1 -1
- package/dist/runtime/citations/components/chat-citation.vue +63 -47
- package/dist/runtime/citations/label.d.ts +7 -0
- package/dist/runtime/citations/label.js +13 -0
- package/dist/runtime/conversations/components/chat-conversation-item.vue +2 -2
- package/dist/runtime/conversations/components/chat-new-conversation-modal.d.vue.ts +1 -1
- package/dist/runtime/conversations/components/chat-new-conversation-modal.vue.d.ts +1 -1
- package/dist/runtime/conversations/composables/conversation-item.d.ts +0 -1
- package/dist/runtime/conversations/composables/conversation-item.js +14 -25
- package/dist/runtime/embed/components/chat-configuration-modal.d.vue.ts +2 -2
- package/dist/runtime/embed/components/chat-configuration-modal.vue.d.ts +2 -2
- package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +1 -1
- package/dist/runtime/embed/components/chat-embed-inner.vue +4 -3
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +1 -1
- package/dist/runtime/embed/components/chat-embed.vue +4 -0
- package/dist/runtime/embed/components/chat-topbar.d.vue.ts +2 -2
- package/dist/runtime/embed/components/chat-topbar.vue.d.ts +2 -2
- package/dist/runtime/embed/components/meistrari-chat-embed.vue +4 -0
- package/dist/runtime/embed/components/mobile/chat-mobile-header.d.vue.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-header.vue.d.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +9 -9
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +9 -9
- package/dist/runtime/embed/composables/embed-config.d.ts +5 -0
- package/dist/runtime/embed/composables/embed-config.js +8 -0
- package/dist/runtime/embed/types.d.ts +11 -0
- package/dist/runtime/messages/components/chat-message-bubble.vue +1 -1
- package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.d.vue.ts +1 -1
- package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +6 -16
- package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue.d.ts +1 -1
- package/dist/runtime/messages/composables/chat.d.ts +1 -1
- package/dist/runtime/messages/composables/chat.js +13 -4
- package/dist/runtime/messages/composables/reasoning-timer.d.ts +2 -1
- package/dist/runtime/messages/composables/reasoning-timer.js +20 -2
- package/dist/runtime/messages/debug/chat-debug-scenarios.js +1 -0
- package/dist/runtime/messages/message-state.js +1 -0
- package/dist/runtime/types/schemas/chat/conversation-runtime.d.ts +4 -0
- package/dist/runtime/types/schemas/chat/conversation-runtime.js +2 -0
- package/dist/runtime/types/schemas/chat/conversations.d.ts +2 -0
- package/dist/runtime/types/schemas/chat/conversations.js +1 -0
- package/dist/runtime/types/schemas/chat/messages.d.ts +3 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -73,6 +73,8 @@ Declared in `src/runtime/embed/types.ts`; prop, feature-flag, and event payload
|
|
|
73
73
|
| `conversationScope` | `string \| null` | `null` | Isolate conversation history by technical scope within the current workspace and runtime. Scoped embeds only see same-scope conversations; values are trimmed, blank becomes `null`, and the server accepts 1-200 chars from `A-Z`, `a-z`, `0-9`, `.`, `_`, `:`, `/`, `-` |
|
|
74
74
|
| `defaultConversationCreatorFilter` | `'all' \| 'mine'` | `'all'` | Initial sidebar creator filter: every conversation in scope, or only the current user's |
|
|
75
75
|
| `availableModels` | `AvailableChatModels` | Full catalog | Non-empty ordered list of models this embed may display and execute. A missing or invalid restored selection falls back to the first entry; an empty list fails fast |
|
|
76
|
+
| `defaultModel` | `ChatModel` | Package default | Initial model for untouched drafts. Explicit selections and existing conversations take precedence; `availableModels` still limits the selection |
|
|
77
|
+
| `defaultReasoningEffort` | `ChatReasoningEffort` | Automatic (`null`) | Initial reasoning effort for untouched drafts. Explicit user choices (including automatic) take precedence |
|
|
76
78
|
| `conversationCreatorFilter` | `'all' \| 'mine'` | — | Controlled sidebar creator filter; use with `v-model:conversation-creator-filter` when the host changes it at runtime |
|
|
77
79
|
| `hideConversationCreatorFilter` | `boolean` | `false` | Hide the creator selector without changing the active filter |
|
|
78
80
|
| `telaAgentId` | `string` | — | Use Tela agent mode for this embed |
|
package/dist/module.json
CHANGED
|
@@ -3,6 +3,7 @@ import { onClickOutside, useElementBounding, useWindowSize } from "@vueuse/core"
|
|
|
3
3
|
import { useEmbedConfig } from "../../embed/composables/embed-config";
|
|
4
4
|
import { useCitationPanel } from "../composables/citation-panel";
|
|
5
5
|
import { useCitations } from "../composables/citations";
|
|
6
|
+
import { stripMarkdownMarkers } from "../label";
|
|
6
7
|
const props = defineProps({
|
|
7
8
|
citation: { type: Object, required: true },
|
|
8
9
|
label: { type: String, required: false }
|
|
@@ -18,7 +19,10 @@ watchEffect(() => {
|
|
|
18
19
|
});
|
|
19
20
|
const status = computed(() => entry.value?.status.value ?? "loading");
|
|
20
21
|
const meta = computed(() => entry.value?.meta.value ?? null);
|
|
21
|
-
const displayLabel = computed(() =>
|
|
22
|
+
const displayLabel = computed(() => {
|
|
23
|
+
const label = props.label ? stripMarkdownMarkers(props.label) : "";
|
|
24
|
+
return label || meta.value?.identifier?.trim() || meta.value?.title?.trim() || "Documento";
|
|
25
|
+
});
|
|
22
26
|
const rootEl = ref(null);
|
|
23
27
|
const popoverEl = ref(null);
|
|
24
28
|
const popoverOpen = ref(false);
|
|
@@ -30,52 +34,64 @@ onClickOutside(rootEl, () => {
|
|
|
30
34
|
const POPOVER_WIDTH = 300;
|
|
31
35
|
const POPOVER_GAP = 6;
|
|
32
36
|
const VIEWPORT_PADDING = 8;
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
37
|
+
const popoverStyle = shallowRef({});
|
|
38
|
+
watch(popoverOpen, (open, _, onCleanup) => {
|
|
39
|
+
if (!open)
|
|
40
|
+
return;
|
|
41
|
+
const scope = effectScope();
|
|
42
|
+
scope.run(() => {
|
|
43
|
+
const triggerBounds = useElementBounding(rootEl);
|
|
44
|
+
const popoverBounds = useElementBounding(popoverEl);
|
|
45
|
+
const viewport = useWindowSize();
|
|
46
|
+
const style = computed(() => {
|
|
47
|
+
const maxHeight = Math.max(
|
|
48
|
+
0,
|
|
49
|
+
viewport.height.value - VIEWPORT_PADDING * 2
|
|
50
|
+
);
|
|
51
|
+
const maxLeft = Math.max(
|
|
52
|
+
VIEWPORT_PADDING,
|
|
53
|
+
viewport.width.value - POPOVER_WIDTH - VIEWPORT_PADDING
|
|
54
|
+
);
|
|
55
|
+
const left = Math.min(
|
|
56
|
+
Math.max(triggerBounds.left.value, VIEWPORT_PADDING),
|
|
57
|
+
maxLeft
|
|
58
|
+
);
|
|
59
|
+
const fitsAbove = triggerBounds.top.value >= popoverBounds.height.value + POPOVER_GAP + VIEWPORT_PADDING;
|
|
60
|
+
const fitsBelow = viewport.height.value - triggerBounds.bottom.value >= popoverBounds.height.value + POPOVER_GAP + VIEWPORT_PADDING;
|
|
61
|
+
const constrainedStyle = {
|
|
62
|
+
left: `${left}px`,
|
|
63
|
+
maxHeight: `${maxHeight}px`,
|
|
64
|
+
overflowY: "auto"
|
|
65
|
+
};
|
|
66
|
+
if (popoverBounds.height.value === 0) {
|
|
67
|
+
return {
|
|
68
|
+
...constrainedStyle,
|
|
69
|
+
top: `${VIEWPORT_PADDING}px`,
|
|
70
|
+
visibility: "hidden"
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
if (fitsAbove) {
|
|
74
|
+
return {
|
|
75
|
+
...constrainedStyle,
|
|
76
|
+
bottom: `${viewport.height.value - triggerBounds.top.value + POPOVER_GAP}px`
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
if (fitsBelow) {
|
|
80
|
+
return {
|
|
81
|
+
...constrainedStyle,
|
|
82
|
+
top: `${triggerBounds.bottom.value + POPOVER_GAP}px`
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
...constrainedStyle,
|
|
87
|
+
top: `${VIEWPORT_PADDING}px`
|
|
88
|
+
};
|
|
89
|
+
});
|
|
90
|
+
watchEffect(() => {
|
|
91
|
+
popoverStyle.value = style.value;
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
onCleanup(() => scope.stop());
|
|
79
95
|
});
|
|
80
96
|
function togglePopover() {
|
|
81
97
|
if (status.value === "loading")
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A citation label is the visible text of `[label](cite://...)`, written by the
|
|
3
|
+
* model, which sometimes wraps it in inline markdown. The chip renders plain
|
|
4
|
+
* text, so the markers that wrap the whole label are removed; anything inside
|
|
5
|
+
* is kept, including markers that only appear in the middle.
|
|
6
|
+
*/
|
|
7
|
+
export declare function stripMarkdownMarkers(label: string): string;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const WRAPPING_MARKER = /^(\*\*|__|\*|_|`+)([\s\S]+)\1$/;
|
|
2
|
+
export function stripMarkdownMarkers(label) {
|
|
3
|
+
let stripped = label.trim();
|
|
4
|
+
let match = stripped.match(WRAPPING_MARKER);
|
|
5
|
+
while (match && !separatesText(match[2], match[1])) {
|
|
6
|
+
stripped = match[2].trim();
|
|
7
|
+
match = stripped.match(WRAPPING_MARKER);
|
|
8
|
+
}
|
|
9
|
+
return stripped;
|
|
10
|
+
}
|
|
11
|
+
function separatesText(inner, marker) {
|
|
12
|
+
return inner.includes(marker) && !(inner.startsWith(marker) && inner.endsWith(marker));
|
|
13
|
+
}
|
|
@@ -20,7 +20,7 @@ const {
|
|
|
20
20
|
confirmDelete,
|
|
21
21
|
cancelDelete,
|
|
22
22
|
handleConversationClick,
|
|
23
|
-
|
|
23
|
+
startRename,
|
|
24
24
|
handleConversationDragStart,
|
|
25
25
|
handleConversationDragEnd,
|
|
26
26
|
cancelRename,
|
|
@@ -81,7 +81,7 @@ function setRenameInputRef(element) {
|
|
|
81
81
|
class="group data-[active=true]:bg-muted data-[active=false]:hover:bg-subtle"
|
|
82
82
|
:data-active="active"
|
|
83
83
|
@click="handleConversationClick"
|
|
84
|
-
@dblclick.prevent.stop="
|
|
84
|
+
@dblclick.prevent.stop="startRename"
|
|
85
85
|
@dragstart="handleConversationDragStart"
|
|
86
86
|
@dragend="handleConversationDragEnd"
|
|
87
87
|
>
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
9
|
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
9
|
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
|
+
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -37,7 +37,6 @@ export declare function useConversationItem(options: ConversationItemOptions, em
|
|
|
37
37
|
cancelDelete: () => void;
|
|
38
38
|
handleConversationClick: (event: MouseEvent) => void;
|
|
39
39
|
startRename: () => void;
|
|
40
|
-
handleConversationDoubleClick: () => void;
|
|
41
40
|
handleConversationDragStart: (event: DragEvent) => void;
|
|
42
41
|
handleConversationDragEnd: () => void;
|
|
43
42
|
cancelRename: () => void;
|
|
@@ -1,15 +1,21 @@
|
|
|
1
1
|
import { resolveConversationRenameTitle } from "../title.js";
|
|
2
2
|
import { capitalizeFirst } from "../../shared/string.js";
|
|
3
|
-
const conversationNavigationDelayMs = 250;
|
|
4
3
|
export function useConversationItem(options, emit) {
|
|
4
|
+
const route = useRoute();
|
|
5
|
+
const router = useRouter();
|
|
5
6
|
const isRenamingInline = ref(false);
|
|
6
7
|
const renameTitle = ref("");
|
|
7
8
|
const renameInputRef = ref(null);
|
|
8
9
|
const isIgnoringInitialRenameBlur = ref(false);
|
|
9
10
|
const showDeleteModal = ref(false);
|
|
10
|
-
const conversationPath = computed(() =>
|
|
11
|
+
const conversationPath = computed(() => {
|
|
12
|
+
if (!options.selectConversation)
|
|
13
|
+
return `/${options.conversation.id}`;
|
|
14
|
+
const query = { ...route.query, conversationId: options.conversation.id };
|
|
15
|
+
delete query.conversation;
|
|
16
|
+
return router.resolve({ path: route.path, query, hash: route.hash }).href;
|
|
17
|
+
});
|
|
11
18
|
const displayTitle = computed(() => capitalizeFirst(options.conversation.title));
|
|
12
|
-
let conversationNavigationTimer = null;
|
|
13
19
|
let renameBlurTimer = null;
|
|
14
20
|
const escapeCancellable = computed(() => isRenamingInline.value || showDeleteModal.value);
|
|
15
21
|
function handleEscapeKeydown(event) {
|
|
@@ -28,12 +34,6 @@ export function useConversationItem(options, emit) {
|
|
|
28
34
|
else
|
|
29
35
|
window.removeEventListener("keydown", handleEscapeKeydown);
|
|
30
36
|
});
|
|
31
|
-
function clearPendingConversationNavigation() {
|
|
32
|
-
if (conversationNavigationTimer === null)
|
|
33
|
-
return;
|
|
34
|
-
clearTimeout(conversationNavigationTimer);
|
|
35
|
-
conversationNavigationTimer = null;
|
|
36
|
-
}
|
|
37
37
|
function clearRenameBlurTimer() {
|
|
38
38
|
if (renameBlurTimer === null)
|
|
39
39
|
return;
|
|
@@ -58,17 +58,13 @@ export function useConversationItem(options, emit) {
|
|
|
58
58
|
if (event.defaultPrevented || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)
|
|
59
59
|
return;
|
|
60
60
|
event.preventDefault();
|
|
61
|
-
clearPendingConversationNavigation();
|
|
62
61
|
if (event.detail > 1)
|
|
63
62
|
return;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
conversationNavigationTimer = null;
|
|
71
|
-
}, conversationNavigationDelayMs);
|
|
63
|
+
if (options.selectConversation) {
|
|
64
|
+
void options.selectConversation(options.conversation.id);
|
|
65
|
+
} else {
|
|
66
|
+
navigateTo(conversationPath.value);
|
|
67
|
+
}
|
|
72
68
|
}
|
|
73
69
|
async function focusRenameInput() {
|
|
74
70
|
await nextTick();
|
|
@@ -77,17 +73,12 @@ export function useConversationItem(options, emit) {
|
|
|
77
73
|
allowRenameBlurSoon();
|
|
78
74
|
}
|
|
79
75
|
function startRename() {
|
|
80
|
-
clearPendingConversationNavigation();
|
|
81
76
|
clearRenameBlurTimer();
|
|
82
77
|
renameTitle.value = options.conversation.title;
|
|
83
78
|
isIgnoringInitialRenameBlur.value = true;
|
|
84
79
|
isRenamingInline.value = true;
|
|
85
80
|
void focusRenameInput();
|
|
86
81
|
}
|
|
87
|
-
function handleConversationDoubleClick() {
|
|
88
|
-
clearPendingConversationNavigation();
|
|
89
|
-
startRename();
|
|
90
|
-
}
|
|
91
82
|
function handleConversationDragStart(event) {
|
|
92
83
|
if (!options.draggable)
|
|
93
84
|
return;
|
|
@@ -146,7 +137,6 @@ export function useConversationItem(options, emit) {
|
|
|
146
137
|
}
|
|
147
138
|
];
|
|
148
139
|
onBeforeUnmount(() => {
|
|
149
|
-
clearPendingConversationNavigation();
|
|
150
140
|
clearRenameBlurTimer();
|
|
151
141
|
if (typeof window !== "undefined")
|
|
152
142
|
window.removeEventListener("keydown", handleEscapeKeydown);
|
|
@@ -163,7 +153,6 @@ export function useConversationItem(options, emit) {
|
|
|
163
153
|
cancelDelete,
|
|
164
154
|
handleConversationClick,
|
|
165
155
|
startRename,
|
|
166
|
-
handleConversationDoubleClick,
|
|
167
156
|
handleConversationDragStart,
|
|
168
157
|
handleConversationDragEnd,
|
|
169
158
|
cancelRename,
|
|
@@ -9,11 +9,11 @@ type __VLS_Props = {
|
|
|
9
9
|
showCredentialsTab?: boolean;
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
12
|
-
"update:open": (value: boolean) => any;
|
|
13
12
|
save: (payload: ChatConfigurationSavePayload) => any;
|
|
13
|
+
"update:open": (value: boolean) => any;
|
|
14
14
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
-
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
16
15
|
onSave?: ((payload: ChatConfigurationSavePayload) => any) | undefined;
|
|
16
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
17
17
|
}>, {
|
|
18
18
|
initialTab: ChatConfigurationTab;
|
|
19
19
|
saving: boolean;
|
|
@@ -9,11 +9,11 @@ type __VLS_Props = {
|
|
|
9
9
|
showCredentialsTab?: boolean;
|
|
10
10
|
};
|
|
11
11
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
12
|
-
"update:open": (value: boolean) => any;
|
|
13
12
|
save: (payload: ChatConfigurationSavePayload) => any;
|
|
13
|
+
"update:open": (value: boolean) => any;
|
|
14
14
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
-
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
16
15
|
onSave?: ((payload: ChatConfigurationSavePayload) => any) | undefined;
|
|
16
|
+
"onUpdate:open"?: ((value: boolean) => any) | undefined;
|
|
17
17
|
}>, {
|
|
18
18
|
initialTab: ChatConfigurationTab;
|
|
19
19
|
saving: boolean;
|
|
@@ -32,10 +32,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
32
32
|
"onUpdate:conversationTitle"?: ((value: string | null) => any) | undefined;
|
|
33
33
|
"onUpdate:conversationCreatorFilter"?: ((value: ConversationCreatorFilter) => any) | undefined;
|
|
34
34
|
}>, {
|
|
35
|
+
compact: boolean;
|
|
35
36
|
hideSettings: boolean;
|
|
36
37
|
hideSidebar: boolean;
|
|
37
38
|
initialConversationId: string | null;
|
|
38
|
-
compact: boolean;
|
|
39
39
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
40
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
41
|
declare const _default: typeof __VLS_export;
|
|
@@ -217,8 +217,7 @@ watch(chatError, (message) => {
|
|
|
217
217
|
if (message)
|
|
218
218
|
statusToast.update({ text: message, icon: "i-ph-warning" });
|
|
219
219
|
});
|
|
220
|
-
const
|
|
221
|
-
const { total, files: conversationFiles } = useConversationFiles(conversationIdRef);
|
|
220
|
+
const { total, files: conversationFiles } = useConversationFiles(activeConversationId);
|
|
222
221
|
function persistConversationModel(conversation, value, wakeAgent) {
|
|
223
222
|
const previousModel = conversation.model;
|
|
224
223
|
setConversationModel(value);
|
|
@@ -347,7 +346,9 @@ async function ensureConversationLoaded(conversationId) {
|
|
|
347
346
|
}
|
|
348
347
|
loadingConversationId.value = conversationId;
|
|
349
348
|
try {
|
|
350
|
-
await loadConversation(conversationId);
|
|
349
|
+
const ownsChatState = await loadConversation(conversationId);
|
|
350
|
+
if (!ownsChatState)
|
|
351
|
+
return;
|
|
351
352
|
if (currentConversation.value?.id !== conversationId) {
|
|
352
353
|
agentWake.skip();
|
|
353
354
|
statusToast.update({
|
|
@@ -32,10 +32,10 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {},
|
|
|
32
32
|
"onUpdate:conversationTitle"?: ((value: string | null) => any) | undefined;
|
|
33
33
|
"onUpdate:conversationCreatorFilter"?: ((value: ConversationCreatorFilter) => any) | undefined;
|
|
34
34
|
}>, {
|
|
35
|
+
compact: boolean;
|
|
35
36
|
hideSettings: boolean;
|
|
36
37
|
hideSidebar: boolean;
|
|
37
38
|
initialConversationId: string | null;
|
|
38
|
-
compact: boolean;
|
|
39
39
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
40
40
|
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
41
41
|
declare const _default: typeof __VLS_export;
|
|
@@ -17,6 +17,8 @@ const props = defineProps({
|
|
|
17
17
|
conversationScope: { type: [String, null], required: false },
|
|
18
18
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
19
19
|
availableModels: { type: Array, required: false },
|
|
20
|
+
defaultModel: { type: null, required: false },
|
|
21
|
+
defaultReasoningEffort: { type: null, required: false },
|
|
20
22
|
conversationCreatorFilter: { type: null, required: false },
|
|
21
23
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
22
24
|
hideSidebar: { type: Boolean, required: false },
|
|
@@ -60,6 +62,8 @@ provideEmbedConfig({
|
|
|
60
62
|
conversationScope: normalizedConversationScope,
|
|
61
63
|
defaultConversationCreatorFilter: computed(() => props.defaultConversationCreatorFilter),
|
|
62
64
|
availableModels: computed(() => props.availableModels),
|
|
65
|
+
defaultModel: computed(() => props.defaultModel),
|
|
66
|
+
defaultReasoningEffort: computed(() => props.defaultReasoningEffort),
|
|
63
67
|
conversationCreatorFilter: computed(() => props.conversationCreatorFilter),
|
|
64
68
|
telaAgentInputs: computed(() => props.telaAgentInputs),
|
|
65
69
|
workspaceSettings: computed(() => props.workspaceSettings),
|
|
@@ -16,10 +16,10 @@ type __VLS_Props = {
|
|
|
16
16
|
};
|
|
17
17
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
18
|
delete: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
19
20
|
rename: () => any;
|
|
20
21
|
duplicate: () => any;
|
|
21
22
|
export: () => any;
|
|
22
|
-
copyLink: () => any;
|
|
23
23
|
debug: () => any;
|
|
24
24
|
tabChange: (tab: TopbarTab) => any;
|
|
25
25
|
cancelEditing: () => any;
|
|
@@ -28,10 +28,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
28
28
|
"update:isEditing": (value: boolean) => any;
|
|
29
29
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
30
30
|
onDelete?: (() => any) | undefined;
|
|
31
|
+
onCopyLink?: (() => any) | undefined;
|
|
31
32
|
onRename?: (() => any) | undefined;
|
|
32
33
|
onDuplicate?: (() => any) | undefined;
|
|
33
34
|
onExport?: (() => any) | undefined;
|
|
34
|
-
onCopyLink?: (() => any) | undefined;
|
|
35
35
|
onDebug?: (() => any) | undefined;
|
|
36
36
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
37
37
|
onCancelEditing?: (() => any) | undefined;
|
|
@@ -16,10 +16,10 @@ type __VLS_Props = {
|
|
|
16
16
|
};
|
|
17
17
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
18
18
|
delete: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
19
20
|
rename: () => any;
|
|
20
21
|
duplicate: () => any;
|
|
21
22
|
export: () => any;
|
|
22
|
-
copyLink: () => any;
|
|
23
23
|
debug: () => any;
|
|
24
24
|
tabChange: (tab: TopbarTab) => any;
|
|
25
25
|
cancelEditing: () => any;
|
|
@@ -28,10 +28,10 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {
|
|
|
28
28
|
"update:isEditing": (value: boolean) => any;
|
|
29
29
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
30
30
|
onDelete?: (() => any) | undefined;
|
|
31
|
+
onCopyLink?: (() => any) | undefined;
|
|
31
32
|
onRename?: (() => any) | undefined;
|
|
32
33
|
onDuplicate?: (() => any) | undefined;
|
|
33
34
|
onExport?: (() => any) | undefined;
|
|
34
|
-
onCopyLink?: (() => any) | undefined;
|
|
35
35
|
onDebug?: (() => any) | undefined;
|
|
36
36
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
37
37
|
onCancelEditing?: (() => any) | undefined;
|
|
@@ -10,6 +10,8 @@ const { hideSidebar = void 0, ...props } = defineProps({
|
|
|
10
10
|
conversationScope: { type: [String, null], required: false },
|
|
11
11
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
12
12
|
availableModels: { type: Array, required: false },
|
|
13
|
+
defaultModel: { type: null, required: false },
|
|
14
|
+
defaultReasoningEffort: { type: null, required: false },
|
|
13
15
|
conversationCreatorFilter: { type: null, required: false },
|
|
14
16
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
15
17
|
hideSidebar: { type: Boolean, required: false },
|
|
@@ -71,6 +73,8 @@ const sharedEmbedProps = computed(() => ({
|
|
|
71
73
|
conversationScope: props.conversationScope,
|
|
72
74
|
defaultConversationCreatorFilter: props.defaultConversationCreatorFilter,
|
|
73
75
|
availableModels: props.availableModels,
|
|
76
|
+
defaultModel: props.defaultModel,
|
|
77
|
+
defaultReasoningEffort: props.defaultReasoningEffort,
|
|
74
78
|
conversationCreatorFilter: props.conversationCreatorFilter,
|
|
75
79
|
hideConversationCreatorFilter: props.hideConversationCreatorFilter,
|
|
76
80
|
hideSettings: hideSettings.value,
|
|
@@ -15,22 +15,22 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
+
openDrawer: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
20
|
+
openOutdatedSettings: () => any;
|
|
18
21
|
rename: () => any;
|
|
19
22
|
duplicate: () => any;
|
|
20
23
|
export: () => any;
|
|
21
|
-
copyLink: () => any;
|
|
22
|
-
openDrawer: () => any;
|
|
23
|
-
openOutdatedSettings: () => any;
|
|
24
24
|
debug: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
+
onCopyLink?: (() => any) | undefined;
|
|
30
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
28
31
|
onRename?: (() => any) | undefined;
|
|
29
32
|
onDuplicate?: (() => any) | undefined;
|
|
30
33
|
onExport?: (() => any) | undefined;
|
|
31
|
-
onCopyLink?: (() => any) | undefined;
|
|
32
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
33
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
34
34
|
onDebug?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
@@ -15,22 +15,22 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
+
openDrawer: () => any;
|
|
19
|
+
copyLink: () => any;
|
|
20
|
+
openOutdatedSettings: () => any;
|
|
18
21
|
rename: () => any;
|
|
19
22
|
duplicate: () => any;
|
|
20
23
|
export: () => any;
|
|
21
|
-
copyLink: () => any;
|
|
22
|
-
openDrawer: () => any;
|
|
23
|
-
openOutdatedSettings: () => any;
|
|
24
24
|
debug: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
+
onCopyLink?: (() => any) | undefined;
|
|
30
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
28
31
|
onRename?: (() => any) | undefined;
|
|
29
32
|
onDuplicate?: (() => any) | undefined;
|
|
30
33
|
onExport?: (() => any) | undefined;
|
|
31
|
-
onCopyLink?: (() => any) | undefined;
|
|
32
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
33
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
34
34
|
onDebug?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
@@ -61,13 +61,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
61
61
|
} & {
|
|
62
62
|
delete: () => any;
|
|
63
63
|
cancel: () => any;
|
|
64
|
+
settings: () => any;
|
|
65
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
66
|
+
copyLink: () => any;
|
|
64
67
|
rename: () => any;
|
|
65
68
|
duplicate: () => any;
|
|
66
69
|
export: () => any;
|
|
67
|
-
copyLink: () => any;
|
|
68
|
-
selectConversation: (id: string) => any;
|
|
69
|
-
settings: () => any;
|
|
70
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
70
|
debug: () => any;
|
|
72
71
|
tabChange: (tab: TopbarTab) => any;
|
|
73
72
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
@@ -76,21 +75,21 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
76
75
|
cancelEditing: () => any;
|
|
77
76
|
dismissOutdatedBanner: () => any;
|
|
78
77
|
saveTitle: () => any;
|
|
78
|
+
selectConversation: (id: string) => any;
|
|
79
79
|
"update:drawerOpen": (value: boolean) => any;
|
|
80
80
|
"update:editTitle": (value: string) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
-
onRename?: (() => any) | undefined;
|
|
86
|
-
onDuplicate?: (() => any) | undefined;
|
|
87
|
-
onExport?: (() => any) | undefined;
|
|
88
|
-
onCopyLink?: (() => any) | undefined;
|
|
89
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
90
85
|
onSettings?: (() => any) | undefined;
|
|
91
86
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
92
87
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
93
88
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
89
|
+
onCopyLink?: (() => any) | undefined;
|
|
90
|
+
onRename?: (() => any) | undefined;
|
|
91
|
+
onDuplicate?: (() => any) | undefined;
|
|
92
|
+
onExport?: (() => any) | undefined;
|
|
94
93
|
onDebug?: (() => any) | undefined;
|
|
95
94
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
96
95
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
@@ -99,6 +98,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
99
98
|
onCancelEditing?: (() => any) | undefined;
|
|
100
99
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
101
100
|
onSaveTitle?: (() => any) | undefined;
|
|
101
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
102
102
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
103
103
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
104
104
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -61,13 +61,12 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
61
61
|
} & {
|
|
62
62
|
delete: () => any;
|
|
63
63
|
cancel: () => any;
|
|
64
|
+
settings: () => any;
|
|
65
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
66
|
+
copyLink: () => any;
|
|
64
67
|
rename: () => any;
|
|
65
68
|
duplicate: () => any;
|
|
66
69
|
export: () => any;
|
|
67
|
-
copyLink: () => any;
|
|
68
|
-
selectConversation: (id: string) => any;
|
|
69
|
-
settings: () => any;
|
|
70
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
70
|
debug: () => any;
|
|
72
71
|
tabChange: (tab: TopbarTab) => any;
|
|
73
72
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
@@ -76,21 +75,21 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
76
75
|
cancelEditing: () => any;
|
|
77
76
|
dismissOutdatedBanner: () => any;
|
|
78
77
|
saveTitle: () => any;
|
|
78
|
+
selectConversation: (id: string) => any;
|
|
79
79
|
"update:drawerOpen": (value: boolean) => any;
|
|
80
80
|
"update:editTitle": (value: string) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
-
onRename?: (() => any) | undefined;
|
|
86
|
-
onDuplicate?: (() => any) | undefined;
|
|
87
|
-
onExport?: (() => any) | undefined;
|
|
88
|
-
onCopyLink?: (() => any) | undefined;
|
|
89
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
90
85
|
onSettings?: (() => any) | undefined;
|
|
91
86
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
92
87
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
93
88
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
89
|
+
onCopyLink?: (() => any) | undefined;
|
|
90
|
+
onRename?: (() => any) | undefined;
|
|
91
|
+
onDuplicate?: (() => any) | undefined;
|
|
92
|
+
onExport?: (() => any) | undefined;
|
|
94
93
|
onDebug?: (() => any) | undefined;
|
|
95
94
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
96
95
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
@@ -99,6 +98,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
99
98
|
onCancelEditing?: (() => any) | undefined;
|
|
100
99
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
101
100
|
onSaveTitle?: (() => any) | undefined;
|
|
101
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
102
102
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
103
103
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
104
104
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatModel, ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
1
2
|
import type { Component, DeepReadonly, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
3
|
import type { ConversationCreatorFilter } from '../../types/schemas/chat/primitives.js';
|
|
3
4
|
import type { WorkspaceSettingsResponse as WorkspaceSettings } from '../../types/schemas/chat/workspace-settings.js';
|
|
@@ -15,6 +16,8 @@ export type EmbedConfig = {
|
|
|
15
16
|
conversationScope: Ref<string | null>;
|
|
16
17
|
defaultConversationCreatorFilter: Ref<ConversationCreatorFilter>;
|
|
17
18
|
availableModels: Ref<AvailableChatModels | undefined>;
|
|
19
|
+
defaultModel: Ref<ChatModel | undefined>;
|
|
20
|
+
defaultReasoningEffort: Ref<ChatReasoningEffort | undefined>;
|
|
18
21
|
conversationCreatorFilter: Ref<ConversationCreatorFilter | undefined>;
|
|
19
22
|
telaAgentInputs: Ref<ConfiguredTelaAgentInputs>;
|
|
20
23
|
workspaceSettings: Ref<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
@@ -36,6 +39,8 @@ type EmbedConfigInput = {
|
|
|
36
39
|
conversationScope?: MaybeRefOrGetter<string | null | undefined>;
|
|
37
40
|
defaultConversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | null | undefined>;
|
|
38
41
|
availableModels?: MaybeRefOrGetter<AvailableChatModels | undefined>;
|
|
42
|
+
defaultModel?: MaybeRefOrGetter<ChatModel | undefined>;
|
|
43
|
+
defaultReasoningEffort?: MaybeRefOrGetter<ChatReasoningEffort | undefined>;
|
|
39
44
|
conversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | undefined>;
|
|
40
45
|
telaAgentInputs?: MaybeRefOrGetter<ConfiguredTelaAgentInputs>;
|
|
41
46
|
workspaceSettings?: MaybeRefOrGetter<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
@@ -23,6 +23,8 @@ function useGlobalEmbedConfigState() {
|
|
|
23
23
|
conversationScope: useState("chat-embed-config-conversation-scope", () => null),
|
|
24
24
|
defaultConversationCreatorFilter: useState("chat-embed-config-default-conversation-creator-filter", () => void 0),
|
|
25
25
|
availableModels: useState("chat-embed-config-available-models", () => void 0),
|
|
26
|
+
defaultModel: useState("chat-embed-config-default-model", () => void 0),
|
|
27
|
+
defaultReasoningEffort: useState("chat-embed-config-default-reasoning-effort", () => void 0),
|
|
26
28
|
conversationCreatorFilter: useState("chat-embed-config-conversation-creator-filter", () => void 0),
|
|
27
29
|
telaAgentInputs: useState("chat-embed-config-tela-agent-inputs", () => void 0),
|
|
28
30
|
workspaceSettings: useState("chat-embed-config-workspace-settings", () => void 0),
|
|
@@ -46,6 +48,8 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
46
48
|
conversationScope: computed(() => normalizeConversationScope(toValue(input.conversationScope))),
|
|
47
49
|
defaultConversationCreatorFilter: computed(() => toValue(input.defaultConversationCreatorFilter) ?? "all"),
|
|
48
50
|
availableModels: computed(() => toValue(input.availableModels)),
|
|
51
|
+
defaultModel: computed(() => toValue(input.defaultModel)),
|
|
52
|
+
defaultReasoningEffort: computed(() => toValue(input.defaultReasoningEffort)),
|
|
49
53
|
conversationCreatorFilter: computed(() => toValue(input.conversationCreatorFilter)),
|
|
50
54
|
telaAgentInputs: computed(() => toValue(input.telaAgentInputs)),
|
|
51
55
|
workspaceSettings: computed(() => toValue(input.workspaceSettings)),
|
|
@@ -70,6 +74,8 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
70
74
|
globalConfig.conversationScope.value = config.conversationScope.value;
|
|
71
75
|
globalConfig.defaultConversationCreatorFilter.value = config.defaultConversationCreatorFilter.value;
|
|
72
76
|
globalConfig.availableModels.value = config.availableModels.value;
|
|
77
|
+
globalConfig.defaultModel.value = config.defaultModel.value;
|
|
78
|
+
globalConfig.defaultReasoningEffort.value = config.defaultReasoningEffort.value;
|
|
73
79
|
globalConfig.conversationCreatorFilter.value = config.conversationCreatorFilter.value;
|
|
74
80
|
globalConfig.telaAgentInputs.value = config.telaAgentInputs.value;
|
|
75
81
|
globalConfig.workspaceSettings.value = config.workspaceSettings.value;
|
|
@@ -101,6 +107,8 @@ export function useEmbedConfig() {
|
|
|
101
107
|
conversationScope: computed(() => globalConfig.conversationScope.value),
|
|
102
108
|
defaultConversationCreatorFilter: computed(() => globalConfig.defaultConversationCreatorFilter.value ?? "all"),
|
|
103
109
|
availableModels: computed(() => globalConfig.availableModels.value),
|
|
110
|
+
defaultModel: computed(() => globalConfig.defaultModel.value),
|
|
111
|
+
defaultReasoningEffort: computed(() => globalConfig.defaultReasoningEffort.value),
|
|
104
112
|
conversationCreatorFilter: computed(() => globalConfig.conversationCreatorFilter.value),
|
|
105
113
|
telaAgentInputs: computed(() => globalConfig.telaAgentInputs.value),
|
|
106
114
|
workspaceSettings: computed(() => globalConfig.workspaceSettings.value),
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatModel, ChatReasoningEffort } from '../types/schemas/chat/models.js';
|
|
1
2
|
import type { Component, DeepReadonly } from 'vue';
|
|
2
3
|
import type { ConversationEvent } from '../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { WorkspaceSettingsResponse as WorkspaceSettings } from '../types/schemas/chat/workspace-settings.js';
|
|
@@ -76,6 +77,16 @@ export type ChatEmbedSharedProps = {
|
|
|
76
77
|
* used when a new or restored selection is not allowed by this list.
|
|
77
78
|
*/
|
|
78
79
|
availableModels?: AvailableChatModels;
|
|
80
|
+
/**
|
|
81
|
+
* Initial model for untouched drafts. Existing conversations and explicit selections take precedence.
|
|
82
|
+
* When excluded by availableModels, the first allowed model is used.
|
|
83
|
+
*/
|
|
84
|
+
defaultModel?: ChatModel;
|
|
85
|
+
/**
|
|
86
|
+
* Initial effort for untouched drafts. Omission preserves automatic reasoning;
|
|
87
|
+
* an explicit user selection (including null) takes precedence.
|
|
88
|
+
*/
|
|
89
|
+
defaultReasoningEffort?: ChatReasoningEffort;
|
|
79
90
|
/** Controlled creator filter. Use with `v-model:conversation-creator-filter` when the host changes it at runtime. */
|
|
80
91
|
conversationCreatorFilter?: ConversationCreatorFilter;
|
|
81
92
|
/** Hide the conversation creator filter while preserving its active value. */
|
|
@@ -196,7 +196,7 @@ const hasDetectedFiles = computed(() => contentSegments.value.some((s) => s.type
|
|
|
196
196
|
:completed="!isPending"
|
|
197
197
|
:preparing-steps="preparingSteps"
|
|
198
198
|
:started-at="message.generationStartedAt ?? message.createdAt"
|
|
199
|
-
:
|
|
199
|
+
:ended-at="message.generationEndedAt"
|
|
200
200
|
/>
|
|
201
201
|
|
|
202
202
|
<div
|
|
@@ -3,7 +3,7 @@ type __VLS_Props = {
|
|
|
3
3
|
reasoningData: ReasoningStep[];
|
|
4
4
|
completed: boolean;
|
|
5
5
|
startedAt: Date | string;
|
|
6
|
-
|
|
6
|
+
endedAt?: Date | string | null;
|
|
7
7
|
preparingSteps?: readonly string[] | null;
|
|
8
8
|
};
|
|
9
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>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { resolveDisplayedReasoning } from "../../reasoning";
|
|
3
|
-
import { useReasoningTimer } from "../../composables/reasoning-timer";
|
|
3
|
+
import { formatThinkingDuration, useReasoningTimer } from "../../composables/reasoning-timer";
|
|
4
4
|
import { resolveToolTitle } from "../../tool-registry";
|
|
5
5
|
import ChatReasoningCollapsibleContent from "./chat-reasoning-collapsible-content.vue";
|
|
6
6
|
import ChatReasoningSteps from "./chat-reasoning-steps.vue";
|
|
@@ -8,14 +8,14 @@ const props = defineProps({
|
|
|
8
8
|
reasoningData: { type: Array, required: true },
|
|
9
9
|
completed: { type: Boolean, required: true },
|
|
10
10
|
startedAt: { type: [Date, String], required: true },
|
|
11
|
-
|
|
11
|
+
endedAt: { type: [Date, String, null], required: false },
|
|
12
12
|
preparingSteps: { type: [Array, null], required: false }
|
|
13
13
|
});
|
|
14
14
|
const TEXT_TRUNCATE_LENGTH = 40;
|
|
15
15
|
const isExpanded = ref(false);
|
|
16
16
|
const { elapsedTime, thinkingDuration } = useReasoningTimer({
|
|
17
17
|
startedAt: computed(() => props.startedAt),
|
|
18
|
-
|
|
18
|
+
endedAt: computed(() => props.endedAt),
|
|
19
19
|
completed: computed(() => props.completed)
|
|
20
20
|
});
|
|
21
21
|
const displayedReasoning = computed(
|
|
@@ -40,18 +40,7 @@ const currentStepName = computed(() => {
|
|
|
40
40
|
}
|
|
41
41
|
return "Trabalhando";
|
|
42
42
|
});
|
|
43
|
-
const formattedDuration = computed(() =>
|
|
44
|
-
if (!thinkingDuration.value)
|
|
45
|
-
return null;
|
|
46
|
-
const seconds = Math.round(thinkingDuration.value / 1e3);
|
|
47
|
-
if (seconds < 60)
|
|
48
|
-
return `${seconds}s`;
|
|
49
|
-
const minutes = Math.floor(seconds / 60);
|
|
50
|
-
const remainingSeconds = seconds % 60;
|
|
51
|
-
if (remainingSeconds === 0)
|
|
52
|
-
return `${minutes}m`;
|
|
53
|
-
return `${minutes}m ${remainingSeconds}s`;
|
|
54
|
-
});
|
|
43
|
+
const formattedDuration = computed(() => formatThinkingDuration(thinkingDuration.value));
|
|
55
44
|
const liveFormattedDuration = computed(() => {
|
|
56
45
|
const seconds = Math.round(elapsedTime.value / 1e3);
|
|
57
46
|
return seconds > 0 ? `${seconds}s` : "";
|
|
@@ -101,7 +90,8 @@ const liveFormattedDuration = computed(() => {
|
|
|
101
90
|
group-hover:text-primary
|
|
102
91
|
transition-colors
|
|
103
92
|
>
|
|
104
|
-
Trabalhou por {{ formattedDuration
|
|
93
|
+
<template v-if="formattedDuration">Trabalhou por {{ formattedDuration }}</template>
|
|
94
|
+
<template v-else>Trabalhou</template>
|
|
105
95
|
</span>
|
|
106
96
|
<div
|
|
107
97
|
v-else
|
|
@@ -3,7 +3,7 @@ type __VLS_Props = {
|
|
|
3
3
|
reasoningData: ReasoningStep[];
|
|
4
4
|
completed: boolean;
|
|
5
5
|
startedAt: Date | string;
|
|
6
|
-
|
|
6
|
+
endedAt?: Date | string | null;
|
|
7
7
|
preparingSteps?: readonly string[] | null;
|
|
8
8
|
};
|
|
9
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>;
|
|
@@ -30,7 +30,7 @@ export declare function useChat(options?: {
|
|
|
30
30
|
cancelling: any;
|
|
31
31
|
generatingTitle: any;
|
|
32
32
|
animatedTitle: any;
|
|
33
|
-
loadConversation: (id: string) => Promise<
|
|
33
|
+
loadConversation: (id: string) => Promise<boolean>;
|
|
34
34
|
setConversation: (conv: Conversation | ConversationWithMessages) => void;
|
|
35
35
|
adoptConversation: (conv: Conversation) => void;
|
|
36
36
|
setConversationModel: (model: string | null) => void;
|
|
@@ -377,7 +377,7 @@ export function useChat(options = {}) {
|
|
|
377
377
|
const pendingModelSelection = computed({
|
|
378
378
|
get: () => {
|
|
379
379
|
const buckets = pendingModelBuckets.value;
|
|
380
|
-
return chatScope.value in buckets ? buckets[chatScope.value] ?? null : defaultChatModel;
|
|
380
|
+
return chatScope.value in buckets ? buckets[chatScope.value] ?? null : embedConfig?.defaultModel?.value ?? defaultChatModel;
|
|
381
381
|
},
|
|
382
382
|
set: (value) => {
|
|
383
383
|
pendingModelBuckets.value = {
|
|
@@ -394,7 +394,7 @@ export function useChat(options = {}) {
|
|
|
394
394
|
};
|
|
395
395
|
const pendingReasoningEffortBuckets = useState("chat-pending-reasoning-effort-selection", () => ({}));
|
|
396
396
|
const pendingReasoningEffortSelection = computed({
|
|
397
|
-
get: () => pendingReasoningEffortBuckets.value[chatScope.value] ?? null,
|
|
397
|
+
get: () => chatScope.value in pendingReasoningEffortBuckets.value ? pendingReasoningEffortBuckets.value[chatScope.value] ?? null : embedConfig?.defaultReasoningEffort?.value ?? null,
|
|
398
398
|
set: (value) => {
|
|
399
399
|
pendingReasoningEffortBuckets.value = {
|
|
400
400
|
...pendingReasoningEffortBuckets.value,
|
|
@@ -427,11 +427,13 @@ export function useChat(options = {}) {
|
|
|
427
427
|
agentSessionRewakeable.value = false;
|
|
428
428
|
error.value = null;
|
|
429
429
|
};
|
|
430
|
+
let loadGeneration = 0;
|
|
430
431
|
const loadConversation = async (id) => {
|
|
431
432
|
if (chatApi.conversationV2Enabled) {
|
|
432
433
|
stopPolling();
|
|
433
434
|
directStream.disconnect();
|
|
434
435
|
}
|
|
436
|
+
const generation = ++loadGeneration;
|
|
435
437
|
runtimeBlocked.value = false;
|
|
436
438
|
loading.value = true;
|
|
437
439
|
error.value = null;
|
|
@@ -440,6 +442,8 @@ export function useChat(options = {}) {
|
|
|
440
442
|
chatApi.path(`/conversations/${id}`),
|
|
441
443
|
chatApi.withChatHeaders()
|
|
442
444
|
);
|
|
445
|
+
if (generation !== loadGeneration)
|
|
446
|
+
return false;
|
|
443
447
|
currentConversation.value = data;
|
|
444
448
|
messages.value = data.messages;
|
|
445
449
|
pendingStreamReconciliationIds.value = /* @__PURE__ */ new Set();
|
|
@@ -457,14 +461,19 @@ export function useChat(options = {}) {
|
|
|
457
461
|
streamingMessageId.value = null;
|
|
458
462
|
directStream.disconnect();
|
|
459
463
|
}
|
|
464
|
+
return true;
|
|
460
465
|
} catch (err) {
|
|
466
|
+
Sentry.captureException(err);
|
|
467
|
+
if (generation !== loadGeneration)
|
|
468
|
+
return false;
|
|
461
469
|
currentConversation.value = null;
|
|
462
470
|
messages.value = [];
|
|
463
471
|
const message = err instanceof Error ? err.message : "Erro ao carregar conversa";
|
|
464
472
|
error.value = message;
|
|
465
|
-
|
|
473
|
+
return true;
|
|
466
474
|
} finally {
|
|
467
|
-
|
|
475
|
+
if (generation === loadGeneration)
|
|
476
|
+
loading.value = false;
|
|
468
477
|
}
|
|
469
478
|
};
|
|
470
479
|
const sendMessage = async (content, files, agentInputs, prepare, queuedSend) => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type Ref } from 'vue';
|
|
2
|
+
export declare function formatThinkingDuration(durationMs: number | null): string | null;
|
|
2
3
|
export declare function useReasoningTimer(options: {
|
|
3
4
|
startedAt: Readonly<Ref<Date | string>>;
|
|
4
|
-
|
|
5
|
+
endedAt: Readonly<Ref<Date | string | null | undefined>>;
|
|
5
6
|
completed: Readonly<Ref<boolean>>;
|
|
6
7
|
}): {
|
|
7
8
|
elapsedTime: Ref<number, number>;
|
|
@@ -1,11 +1,29 @@
|
|
|
1
1
|
import { computed, ref, watch } from "vue";
|
|
2
|
+
const MINUTE_SECONDS = 60;
|
|
3
|
+
const HOUR_SECONDS = 60 * MINUTE_SECONDS;
|
|
4
|
+
const DAY_SECONDS = 24 * HOUR_SECONDS;
|
|
5
|
+
function withRemainder(whole, wholeUnit, remainder, remainderUnit) {
|
|
6
|
+
return remainder === 0 ? `${whole}${wholeUnit}` : `${whole}${wholeUnit} ${remainder}${remainderUnit}`;
|
|
7
|
+
}
|
|
8
|
+
export function formatThinkingDuration(durationMs) {
|
|
9
|
+
if (!durationMs)
|
|
10
|
+
return null;
|
|
11
|
+
const seconds = Math.round(durationMs / 1e3);
|
|
12
|
+
if (seconds < MINUTE_SECONDS)
|
|
13
|
+
return `${seconds}s`;
|
|
14
|
+
if (seconds < HOUR_SECONDS)
|
|
15
|
+
return withRemainder(Math.floor(seconds / MINUTE_SECONDS), "m", seconds % MINUTE_SECONDS, "s");
|
|
16
|
+
if (seconds < DAY_SECONDS)
|
|
17
|
+
return withRemainder(Math.floor(seconds / HOUR_SECONDS), "h", Math.floor(seconds % HOUR_SECONDS / MINUTE_SECONDS), "m");
|
|
18
|
+
return withRemainder(Math.floor(seconds / DAY_SECONDS), "d", Math.floor(seconds % DAY_SECONDS / HOUR_SECONDS), "h");
|
|
19
|
+
}
|
|
2
20
|
export function useReasoningTimer(options) {
|
|
3
21
|
const elapsedTime = ref(0);
|
|
4
22
|
const startTime = computed(() => new Date(options.startedAt.value).getTime());
|
|
5
23
|
const thinkingDuration = computed(() => {
|
|
6
|
-
if (!options.
|
|
24
|
+
if (!options.endedAt.value)
|
|
7
25
|
return null;
|
|
8
|
-
const duration = new Date(options.
|
|
26
|
+
const duration = new Date(options.endedAt.value).getTime() - startTime.value;
|
|
9
27
|
return Number.isFinite(duration) && duration >= 0 ? duration : null;
|
|
10
28
|
});
|
|
11
29
|
watch([startTime, options.completed], ([start, completed], _previous, onCleanup) => {
|
|
@@ -89,6 +89,7 @@ function message(baseTime, offsetMs, input) {
|
|
|
89
89
|
externalUuid: null,
|
|
90
90
|
ttft: null,
|
|
91
91
|
generationStartedAt: null,
|
|
92
|
+
generationEndedAt: input.updatedAt ?? null,
|
|
92
93
|
createdBy: input.role === "user" ? "debugger@tela.com" : null,
|
|
93
94
|
createdAt,
|
|
94
95
|
updatedAt: input.updatedAt ?? createdAt,
|
|
@@ -115,6 +115,7 @@ export declare const sendMessageV2ResponseSchema: z.ZodObject<{
|
|
|
115
115
|
createdAt: z.ZodDate;
|
|
116
116
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
117
117
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
118
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
118
119
|
}, z.core.$strip>;
|
|
119
120
|
assistantMessage: z.ZodObject<{
|
|
120
121
|
id: z.ZodString;
|
|
@@ -148,6 +149,7 @@ export declare const sendMessageV2ResponseSchema: z.ZodObject<{
|
|
|
148
149
|
createdAt: z.ZodDate;
|
|
149
150
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
150
151
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
152
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
151
153
|
}, z.core.$strip>;
|
|
152
154
|
turn: z.ZodNullable<z.ZodObject<{
|
|
153
155
|
id: z.ZodString;
|
|
@@ -228,6 +230,8 @@ export declare const conversationRuntimeWebhookPayloadSchema: z.ZodObject<{
|
|
|
228
230
|
"session.waiting_messages": "session.waiting_messages";
|
|
229
231
|
}>;
|
|
230
232
|
sessionId: z.ZodString;
|
|
233
|
+
runId: z.ZodOptional<z.ZodString>;
|
|
234
|
+
timestamp: z.ZodOptional<z.ZodString>;
|
|
231
235
|
status: z.ZodOptional<z.ZodString>;
|
|
232
236
|
error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
233
237
|
failReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -58,6 +58,8 @@ export const conversationRuntimeWebhookPayloadSchema = z.object({
|
|
|
58
58
|
'session.waiting_messages',
|
|
59
59
|
]),
|
|
60
60
|
sessionId: z.string().min(1),
|
|
61
|
+
runId: z.string().optional(),
|
|
62
|
+
timestamp: z.string().optional(),
|
|
61
63
|
status: z.string().optional(),
|
|
62
64
|
error: z.string().nullable().optional(),
|
|
63
65
|
failReason: z.string().nullable().optional(),
|
|
@@ -111,6 +111,7 @@ export declare const messageSchema: z.ZodObject<{
|
|
|
111
111
|
createdAt: z.ZodDate;
|
|
112
112
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
113
113
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
114
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
114
115
|
}, z.core.$strip>;
|
|
115
116
|
export type Message = z.infer<typeof messageSchema>;
|
|
116
117
|
export declare const conversationCreatorFilterCountsSchema: z.ZodRecord<z.ZodEnum<{
|
|
@@ -224,6 +225,7 @@ export declare const conversationWithMessagesSchema: z.ZodObject<{
|
|
|
224
225
|
createdAt: z.ZodDate;
|
|
225
226
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
226
227
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
228
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
227
229
|
}, z.core.$strip>>;
|
|
228
230
|
}, z.core.$strip>;
|
|
229
231
|
export type ConversationWithMessages = z.infer<typeof conversationWithMessagesSchema>;
|
|
@@ -50,6 +50,7 @@ export const messageSchema = z.object({
|
|
|
50
50
|
createdAt: z.date(),
|
|
51
51
|
updatedAt: z.date().nullable(),
|
|
52
52
|
generationStartedAt: z.date().nullable(),
|
|
53
|
+
generationEndedAt: z.date().nullable().optional(),
|
|
53
54
|
});
|
|
54
55
|
export const conversationCreatorFilterCountsSchema = z.record(conversationCreatorFilterSchema, z.number());
|
|
55
56
|
export const conversationListMetadataSchema = z.object({
|
|
@@ -120,6 +120,7 @@ export declare const sendMessageResponseSchema: z.ZodObject<{
|
|
|
120
120
|
createdAt: z.ZodDate;
|
|
121
121
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
122
122
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
123
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
123
124
|
}, z.core.$strip>;
|
|
124
125
|
assistantMessage: z.ZodObject<{
|
|
125
126
|
id: z.ZodString;
|
|
@@ -153,6 +154,7 @@ export declare const sendMessageResponseSchema: z.ZodObject<{
|
|
|
153
154
|
createdAt: z.ZodDate;
|
|
154
155
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
155
156
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
157
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
156
158
|
}, z.core.$strip>;
|
|
157
159
|
}, z.core.$strip>;
|
|
158
160
|
export type SendMessageResponse = z.infer<typeof sendMessageResponseSchema>;
|
|
@@ -189,6 +191,7 @@ export declare const messagePollResponseSchema: z.ZodObject<{
|
|
|
189
191
|
createdAt: z.ZodDate;
|
|
190
192
|
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
191
193
|
generationStartedAt: z.ZodNullable<z.ZodDate>;
|
|
194
|
+
generationEndedAt: z.ZodOptional<z.ZodNullable<z.ZodDate>>;
|
|
192
195
|
}, z.core.$strip>>;
|
|
193
196
|
newFiles: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
194
197
|
url: z.ZodString;
|