@meistrari/chat-nuxt 1.3.0 → 1.5.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 +51 -16
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -8
- package/dist/runtime/components/MeistrariChatEmbed.d.vue.ts +5 -16
- package/dist/runtime/components/MeistrariChatEmbed.vue +28 -5
- package/dist/runtime/components/MeistrariChatEmbed.vue.d.ts +5 -16
- package/dist/runtime/components/app-markdown-render.d.vue.ts +3 -1
- package/dist/runtime/components/app-markdown-render.vue +15 -4
- package/dist/runtime/components/app-markdown-render.vue.d.ts +3 -1
- package/dist/runtime/components/chat/message-bubble.vue +10 -2
- package/dist/runtime/components/chat/message-input.d.vue.ts +30 -4
- package/dist/runtime/components/chat/message-input.vue +268 -24
- package/dist/runtime/components/chat/message-input.vue.d.ts +30 -4
- package/dist/runtime/composables/useChat.d.ts +3 -5
- package/dist/runtime/composables/useChat.js +24 -3
- package/dist/runtime/composables/useChatAction.d.ts +10 -0
- package/dist/runtime/composables/useChatAction.js +12 -0
- package/dist/runtime/composables/useChatApi.js +4 -0
- package/dist/runtime/composables/useConversations.js +8 -2
- package/dist/runtime/composables/useEmbedConfig.d.ts +12 -2
- package/dist/runtime/composables/useEmbedConfig.js +24 -3
- package/dist/runtime/composables/useFeatureFlags.d.ts +1 -2
- package/dist/runtime/composables/useTelaAgentMetadata.d.ts +8 -0
- package/dist/runtime/composables/useTelaAgentMetadata.js +65 -0
- package/dist/runtime/composables/useWorkspaceSettings.d.ts +1 -19
- package/dist/runtime/embed/components/ChatConfigurationModal.d.vue.ts +1 -1
- package/dist/runtime/embed/components/ChatConfigurationModal.vue.d.ts +1 -1
- package/dist/runtime/embed/components/ChatEmbed.d.vue.ts +6 -21
- package/dist/runtime/embed/components/ChatEmbed.vue +44 -11
- package/dist/runtime/embed/components/ChatEmbed.vue.d.ts +6 -21
- package/dist/runtime/embed/components/ChatEmbedInner.vue +36 -12
- package/dist/runtime/plugins/markstream.d.ts +1 -1
- package/dist/runtime/plugins/markstream.js +1 -1
- package/dist/runtime/server/api/conversations/[id]/cancel.post.d.ts +1 -1
- package/dist/runtime/server/api/conversations/[id]/cancel.post.js +37 -17
- package/dist/runtime/server/api/conversations/[id]/clear.post.js +28 -13
- package/dist/runtime/server/api/conversations/[id]/duplicate.post.js +11 -13
- package/dist/runtime/server/api/conversations/[id]/files.get.js +5 -7
- package/dist/runtime/server/api/conversations/[id]/index.delete.js +13 -12
- package/dist/runtime/server/api/conversations/[id]/index.get.js +6 -13
- package/dist/runtime/server/api/conversations/[id]/index.patch.js +11 -10
- package/dist/runtime/server/api/conversations/[id]/messages/[messageId]/retry.post.js +46 -80
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.d.ts +1 -14
- package/dist/runtime/server/api/conversations/[id]/messages/index.get.js +81 -187
- package/dist/runtime/server/api/conversations/[id]/messages/index.post.js +68 -83
- package/dist/runtime/server/api/conversations/[id]/usage.get.js +4 -8
- package/dist/runtime/server/api/conversations/generate-title.post.js +4 -3
- package/dist/runtime/server/api/conversations/index.get.js +5 -4
- package/dist/runtime/server/api/conversations/index.post.js +5 -4
- package/dist/runtime/server/api/tela/agents/[id].get.d.ts +6 -0
- package/dist/runtime/server/api/tela/agents/[id].get.js +25 -0
- package/dist/runtime/server/api/workspace/settings.patch.js +1 -1
- package/dist/runtime/server/db/index.js +62 -0
- package/dist/runtime/server/db/schema/conversations.d.ts +17 -0
- package/dist/runtime/server/db/schema/conversations.js +3 -1
- package/dist/runtime/server/db/schema/workspace-settings.d.ts +1 -1
- package/dist/runtime/server/utils/agent-api.d.ts +1 -1
- package/dist/runtime/server/utils/agent-api.js +2 -5
- package/dist/runtime/server/utils/chat-context.d.ts +5 -0
- package/dist/runtime/server/utils/chat-context.js +20 -0
- package/dist/runtime/server/utils/chat-workspace-settings.d.ts +2 -1
- package/dist/runtime/server/utils/chat-workspace-settings.js +10 -1
- package/dist/runtime/server/utils/conversation-agent-turn.d.ts +39 -0
- package/dist/runtime/server/utils/conversation-agent-turn.js +170 -0
- package/dist/runtime/server/utils/conversation-message-files.d.ts +10 -0
- package/dist/runtime/server/utils/conversation-message-files.js +77 -0
- package/dist/runtime/server/utils/conversation-message-sync.d.ts +31 -0
- package/dist/runtime/server/utils/conversation-message-sync.js +132 -0
- package/dist/runtime/server/utils/conversation-scope.d.ts +2 -0
- package/dist/runtime/server/utils/conversation-scope.js +12 -0
- package/dist/runtime/server/utils/tela-agent-api.d.ts +29 -0
- package/dist/runtime/server/utils/tela-agent-api.js +107 -0
- package/dist/runtime/server/utils/tela-agent-session.d.ts +48 -0
- package/dist/runtime/server/utils/tela-agent-session.js +350 -0
- package/dist/runtime/types/embed.d.ts +29 -0
- package/dist/runtime/types/embed.js +0 -0
- package/dist/runtime/types/tela-agent.d.ts +243 -0
- package/dist/runtime/types/tela-agent.js +98 -0
- package/dist/runtime/types/workspace-settings-data.d.ts +19 -0
- package/dist/runtime/types/workspace-settings-data.js +0 -0
- package/dist/runtime/types/workspace-settings.d.ts +1 -1
- package/dist/runtime/utils/agent-input-readiness.d.ts +14 -0
- package/dist/runtime/utils/agent-input-readiness.js +15 -0
- package/dist/runtime/utils/custom-markdown-components.d.ts +9 -0
- package/dist/runtime/utils/custom-markdown-components.js +54 -0
- package/dist/runtime/utils/features.d.ts +9 -0
- package/dist/runtime/utils/features.js +5 -4
- package/dist/runtime/utils/file.js +46 -7
- package/dist/runtime/utils/markdown-nodes.d.ts +1 -0
- package/dist/runtime/utils/markdown-nodes.js +6 -0
- package/dist/runtime/utils/tela-chat.d.ts +6 -0
- package/dist/runtime/utils/tela-chat.js +12 -1
- package/drizzle/0014_faulty_lake.sql +2 -0
- package/drizzle/meta/0014_snapshot.json +732 -0
- package/drizzle/meta/_journal.json +7 -0
- package/package.json +1 -1
- package/dist/runtime/types/feature-flags.d.ts +0 -7
- package/dist/runtime/types/feature-flags.js +0 -6
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { DEFAULT_MODEL } from "../../types/chat";
|
|
3
3
|
import { formatFileSize, getMimeIcon, getMimeLabel } from "../../utils/file";
|
|
4
|
+
import { getAgentInputReadiness } from "../../utils/agent-input-readiness";
|
|
4
5
|
import { MAX_FILE_SIZE, MAX_FILES } from "../../composables/useWorkspaceContextFiles";
|
|
5
|
-
import { FEATURE_FLAGS } from "../../types/feature-flags";
|
|
6
6
|
const props = defineProps({
|
|
7
7
|
disabled: { type: Boolean, required: false },
|
|
8
8
|
loading: { type: Boolean, required: false },
|
|
@@ -13,19 +13,48 @@ const props = defineProps({
|
|
|
13
13
|
hasDisclaimer: { type: Boolean, required: false },
|
|
14
14
|
messages: { type: Array, required: false },
|
|
15
15
|
conversationFiles: { type: Array, required: false },
|
|
16
|
-
workspaceSettings: { type: null, required: false }
|
|
16
|
+
workspaceSettings: { type: null, required: false },
|
|
17
|
+
allowModelSelection: { type: Boolean, required: false },
|
|
18
|
+
agentInputSchema: { type: null, required: false },
|
|
19
|
+
agentInputSchemaLoading: { type: Boolean, required: false },
|
|
20
|
+
showModelSelector: { type: Boolean, required: false },
|
|
21
|
+
showCancelButton: { type: Boolean, required: false }
|
|
17
22
|
});
|
|
18
23
|
const emit = defineEmits(["send", "cancel"]);
|
|
19
24
|
const selectedModel = defineModel("model", { type: null, ...{ default: DEFAULT_MODEL } });
|
|
20
25
|
const { uploadFiles, uploading, uploadError } = useFileUpload();
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const isModelSelectorEnabled = computed(() => isFeatureEnabled(FEATURE_FLAGS.ENABLE_MODEL_SELECTOR));
|
|
26
|
+
const isCancelEnabled = computed(() => props.showCancelButton === true);
|
|
27
|
+
const isModelSelectorEnabled = computed(() => props.showModelSelector === true && props.allowModelSelection !== false);
|
|
24
28
|
const content = ref("");
|
|
25
29
|
const editorRef = ref(null);
|
|
26
30
|
const fileInputRef = ref(null);
|
|
27
31
|
const pendingFiles = ref([]);
|
|
32
|
+
const selectedUploadInputName = ref(void 0);
|
|
33
|
+
const agentInputTexts = ref({});
|
|
34
|
+
const isAgentInputsOpen = ref(false);
|
|
28
35
|
const isLocked = computed(() => props.disabled || props.loading);
|
|
36
|
+
const agentInputVariables = computed(
|
|
37
|
+
() => (props.agentInputSchema ?? []).filter((input) => input.name.trim())
|
|
38
|
+
);
|
|
39
|
+
const fileInputVariables = computed(
|
|
40
|
+
() => agentInputVariables.value.filter((input) => input.type === "file")
|
|
41
|
+
);
|
|
42
|
+
const textInputVariables = computed(
|
|
43
|
+
() => agentInputVariables.value.filter((input) => input.type === "text")
|
|
44
|
+
);
|
|
45
|
+
const hasAgentInputs = computed(() => agentInputVariables.value.length > 0);
|
|
46
|
+
const requiredAgentInputCount = computed(
|
|
47
|
+
() => agentInputVariables.value.filter((input) => input.required).length
|
|
48
|
+
);
|
|
49
|
+
const defaultFileInputName = computed(
|
|
50
|
+
() => fileInputVariables.value.length === 1 ? fileInputVariables.value[0]?.name : void 0
|
|
51
|
+
);
|
|
52
|
+
const agentInputReadiness = computed(() => getAgentInputReadiness({
|
|
53
|
+
inputVariables: agentInputVariables.value,
|
|
54
|
+
inputTexts: agentInputTexts.value,
|
|
55
|
+
files: pendingFiles.value
|
|
56
|
+
}));
|
|
57
|
+
const hasUnmappedAgentFiles = computed(() => agentInputReadiness.value.hasUnmappedFiles);
|
|
29
58
|
const messagesRef = computed(() => props.messages ?? []);
|
|
30
59
|
const inputHistory = useInputHistory(messagesRef);
|
|
31
60
|
let restoringHistory = false;
|
|
@@ -92,9 +121,21 @@ const mentionAutocomplete = useMentionAutocomplete({
|
|
|
92
121
|
onInsert: handleInput
|
|
93
122
|
});
|
|
94
123
|
const canSend = computed(
|
|
95
|
-
() => content.value.trim().length > 0 && !isLocked.value && !uploading.value
|
|
124
|
+
() => content.value.trim().length > 0 && !isLocked.value && !uploading.value && !props.agentInputSchemaLoading && agentInputReadiness.value.ready
|
|
96
125
|
);
|
|
97
|
-
|
|
126
|
+
watch(agentInputVariables, (variables) => {
|
|
127
|
+
const variableNames = new Set(variables.map((input) => input.name));
|
|
128
|
+
agentInputTexts.value = Object.fromEntries(
|
|
129
|
+
Object.entries(agentInputTexts.value).filter(([name]) => variableNames.has(name))
|
|
130
|
+
);
|
|
131
|
+
pendingFiles.value = pendingFiles.value.map((pendingFile) => {
|
|
132
|
+
if (!pendingFile.inputName || variableNames.has(pendingFile.inputName))
|
|
133
|
+
return pendingFile;
|
|
134
|
+
return { ...pendingFile, inputName: void 0 };
|
|
135
|
+
});
|
|
136
|
+
}, { deep: true });
|
|
137
|
+
function openFileDialog(inputName) {
|
|
138
|
+
selectedUploadInputName.value = inputName ?? defaultFileInputName.value;
|
|
98
139
|
fileInputRef.value?.click();
|
|
99
140
|
}
|
|
100
141
|
function handleFileSelect(event) {
|
|
@@ -107,28 +148,100 @@ function handleFileSelect(event) {
|
|
|
107
148
|
}
|
|
108
149
|
return true;
|
|
109
150
|
});
|
|
110
|
-
|
|
111
|
-
|
|
151
|
+
queueFiles(newFiles, selectedUploadInputName.value);
|
|
152
|
+
selectedUploadInputName.value = void 0;
|
|
112
153
|
target.value = "";
|
|
113
154
|
}
|
|
114
|
-
function
|
|
115
|
-
|
|
155
|
+
function createPendingFile(file, inputName) {
|
|
156
|
+
return {
|
|
157
|
+
id: `${file.name}-${file.lastModified}-${file.size}-${Math.random().toString(36).slice(2)}`,
|
|
158
|
+
file,
|
|
159
|
+
inputName
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
function queueFiles(files, inputName) {
|
|
163
|
+
const availableSlots = MAX_FILES - pendingFiles.value.length;
|
|
164
|
+
if (availableSlots <= 0)
|
|
165
|
+
return;
|
|
166
|
+
const mappedInputName = inputName ?? defaultFileInputName.value;
|
|
167
|
+
pendingFiles.value = [
|
|
168
|
+
...pendingFiles.value,
|
|
169
|
+
...files.slice(0, availableSlots).map((file) => createPendingFile(file, mappedInputName))
|
|
170
|
+
];
|
|
171
|
+
}
|
|
172
|
+
function removeFile(id) {
|
|
173
|
+
pendingFiles.value = pendingFiles.value.filter((file) => file.id !== id);
|
|
174
|
+
}
|
|
175
|
+
function updatePendingFileInput(id, event) {
|
|
176
|
+
const value = event.target.value;
|
|
177
|
+
pendingFiles.value = pendingFiles.value.map((file) => {
|
|
178
|
+
if (file.id !== id)
|
|
179
|
+
return file;
|
|
180
|
+
return { ...file, inputName: value || void 0 };
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function countFilesForInput(inputName) {
|
|
184
|
+
return pendingFiles.value.filter((file) => file.inputName === inputName).length;
|
|
185
|
+
}
|
|
186
|
+
function handleVariableDrop(event, inputName) {
|
|
187
|
+
const files = event.dataTransfer?.files ? Array.from(event.dataTransfer.files) : [];
|
|
188
|
+
addFiles(files, inputName);
|
|
189
|
+
}
|
|
190
|
+
function getVaultRef(file) {
|
|
191
|
+
return file.vaultReference?.trim() || (file.url.startsWith("vault://") ? file.url : null);
|
|
192
|
+
}
|
|
193
|
+
function buildAgentInputs(files, queuedFiles) {
|
|
194
|
+
if (!hasAgentInputs.value)
|
|
195
|
+
return [];
|
|
196
|
+
const inputs = [];
|
|
197
|
+
for (const input of textInputVariables.value) {
|
|
198
|
+
const text = (agentInputTexts.value[input.name] ?? "").trim();
|
|
199
|
+
if (!text)
|
|
200
|
+
continue;
|
|
201
|
+
inputs.push({
|
|
202
|
+
type: "text",
|
|
203
|
+
name: input.name,
|
|
204
|
+
content: text
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
files.forEach((file, index) => {
|
|
208
|
+
const inputName = queuedFiles[index]?.inputName;
|
|
209
|
+
const vaultRef = getVaultRef(file);
|
|
210
|
+
if (!inputName || !vaultRef)
|
|
211
|
+
return;
|
|
212
|
+
inputs.push({
|
|
213
|
+
type: "file",
|
|
214
|
+
name: inputName,
|
|
215
|
+
vaultRef,
|
|
216
|
+
filename: file.name.slice(0, 255)
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
return inputs;
|
|
116
220
|
}
|
|
117
221
|
async function handleSend() {
|
|
118
222
|
if (!canSend.value)
|
|
119
223
|
return;
|
|
120
224
|
let files = [];
|
|
121
|
-
|
|
225
|
+
const queuedFiles = [...pendingFiles.value];
|
|
226
|
+
if (queuedFiles.length > 0) {
|
|
122
227
|
try {
|
|
123
|
-
files = await uploadFiles(
|
|
228
|
+
files = await uploadFiles(queuedFiles.map((item) => item.file));
|
|
124
229
|
} catch {
|
|
125
230
|
return;
|
|
126
231
|
}
|
|
127
232
|
}
|
|
128
233
|
const taggedContent = mentionAutocomplete.buildTaggedContent();
|
|
129
|
-
|
|
234
|
+
const agentInputs = buildAgentInputs(files, queuedFiles);
|
|
235
|
+
emit(
|
|
236
|
+
"send",
|
|
237
|
+
taggedContent.trim(),
|
|
238
|
+
files,
|
|
239
|
+
isModelSelectorEnabled.value ? selectedModel.value : void 0,
|
|
240
|
+
agentInputs.length > 0 ? agentInputs : void 0
|
|
241
|
+
);
|
|
130
242
|
content.value = "";
|
|
131
243
|
pendingFiles.value = [];
|
|
244
|
+
agentInputTexts.value = {};
|
|
132
245
|
mentionAutocomplete.resetMentions();
|
|
133
246
|
inputHistory.resetNavigation();
|
|
134
247
|
nextTick(() => {
|
|
@@ -273,15 +386,14 @@ function focusEditor() {
|
|
|
273
386
|
return;
|
|
274
387
|
editorRef.value?.focus();
|
|
275
388
|
}
|
|
276
|
-
function addFiles(files) {
|
|
389
|
+
function addFiles(files, inputName) {
|
|
277
390
|
const validFiles = files.filter((file) => {
|
|
278
391
|
if (file.size > MAX_FILE_SIZE) {
|
|
279
392
|
return false;
|
|
280
393
|
}
|
|
281
394
|
return true;
|
|
282
395
|
});
|
|
283
|
-
|
|
284
|
-
pendingFiles.value = [...pendingFiles.value, ...validFiles.slice(0, availableSlots)];
|
|
396
|
+
queueFiles(validFiles, inputName);
|
|
285
397
|
}
|
|
286
398
|
defineExpose({
|
|
287
399
|
addFiles
|
|
@@ -291,11 +403,120 @@ defineExpose({
|
|
|
291
403
|
<template>
|
|
292
404
|
<div :class="centered ? '' : hasDisclaimer ? 'px-24px' : 'px-24px pb-24px'" bg-transparent>
|
|
293
405
|
<div :class="centered ? 'w-700px' : 'max-w-800px'" mx-auto>
|
|
406
|
+
<Transition name="agent-inputs-panel-motion" mode="out-in" appear>
|
|
407
|
+
<div
|
|
408
|
+
v-if="hasAgentInputs"
|
|
409
|
+
class="agent-inputs-panel"
|
|
410
|
+
mb-6px
|
|
411
|
+
rounded-12px
|
|
412
|
+
b=".5px gray-200"
|
|
413
|
+
bg-white
|
|
414
|
+
overflow-hidden
|
|
415
|
+
>
|
|
416
|
+
<button
|
|
417
|
+
type="button"
|
|
418
|
+
w-full
|
|
419
|
+
flex
|
|
420
|
+
items-center
|
|
421
|
+
gap-8px
|
|
422
|
+
h-40px
|
|
423
|
+
px-12px
|
|
424
|
+
text-left
|
|
425
|
+
hover:bg-gray-50
|
|
426
|
+
transition-colors
|
|
427
|
+
@click.stop="isAgentInputsOpen = !isAgentInputsOpen"
|
|
428
|
+
>
|
|
429
|
+
<span i-ph-brackets-curly text-14px text-gray-500 />
|
|
430
|
+
<span text-13px font-580 text-gray-800>Variáveis</span>
|
|
431
|
+
<span px-6px py-2px rounded-4px bg-gray-100 text-11px text-gray-600>{{ agentInputVariables.length }}</span>
|
|
432
|
+
<span v-if="requiredAgentInputCount" text-11px text-gray-400>{{ requiredAgentInputCount }} obrigatória(s)</span>
|
|
433
|
+
<div flex-1 />
|
|
434
|
+
<span
|
|
435
|
+
i-ph-caret-down-bold
|
|
436
|
+
text-12px
|
|
437
|
+
text-gray-400
|
|
438
|
+
transition-transform
|
|
439
|
+
:class="{ 'rotate-180': isAgentInputsOpen }"
|
|
440
|
+
/>
|
|
441
|
+
</button>
|
|
442
|
+
|
|
443
|
+
<Transition name="agent-inputs-content">
|
|
444
|
+
<div v-if="isAgentInputsOpen" class="agent-inputs-content" flex="~ col" gap-10px px-12px pb-12px @click.stop>
|
|
445
|
+
<label
|
|
446
|
+
v-for="input in textInputVariables"
|
|
447
|
+
:key="`text-${input.id || input.name}`"
|
|
448
|
+
flex="~ col"
|
|
449
|
+
gap-6px
|
|
450
|
+
>
|
|
451
|
+
<span flex items-center gap-6px text-12px font-580 text-gray-700>
|
|
452
|
+
<span w-6px h-6px rounded-full bg-blue-400 />
|
|
453
|
+
{{ input.name }}<span v-if="input.required" text-orange-500>*</span>
|
|
454
|
+
</span>
|
|
455
|
+
<textarea
|
|
456
|
+
v-model="agentInputTexts[input.name]"
|
|
457
|
+
class="agent-text-input"
|
|
458
|
+
:placeholder="input.description || input.name"
|
|
459
|
+
:disabled="isLocked"
|
|
460
|
+
rows="2"
|
|
461
|
+
/>
|
|
462
|
+
</label>
|
|
463
|
+
|
|
464
|
+
<div
|
|
465
|
+
v-for="input in fileInputVariables"
|
|
466
|
+
:key="`file-${input.id || input.name}`"
|
|
467
|
+
class="agent-file-input-row"
|
|
468
|
+
rounded-10px
|
|
469
|
+
b=".5px dashed gray-300"
|
|
470
|
+
p-10px
|
|
471
|
+
flex
|
|
472
|
+
items-center
|
|
473
|
+
gap-10px
|
|
474
|
+
transition-colors
|
|
475
|
+
:class="isLocked ? 'opacity-60' : 'hover:bg-gray-50 cursor-pointer'"
|
|
476
|
+
@click.stop="openFileDialog(input.name)"
|
|
477
|
+
@dragover.prevent
|
|
478
|
+
@drop.stop.prevent="handleVariableDrop($event, input.name)"
|
|
479
|
+
>
|
|
480
|
+
<span w-6px h-6px rounded-full bg-orange-400 shrink-0 />
|
|
481
|
+
<div flex="~ col" min-w-0 flex-1>
|
|
482
|
+
<span text-12px font-580 text-gray-700 truncate>
|
|
483
|
+
{{ input.name }}<span v-if="input.required" text-orange-500>*</span>
|
|
484
|
+
</span>
|
|
485
|
+
<span v-if="input.description" text-11px text-gray-400 truncate>{{ input.description }}</span>
|
|
486
|
+
</div>
|
|
487
|
+
<span
|
|
488
|
+
v-if="countFilesForInput(input.name) > 0"
|
|
489
|
+
px-6px
|
|
490
|
+
py-2px
|
|
491
|
+
rounded-4px
|
|
492
|
+
bg-orange-50
|
|
493
|
+
text-11px
|
|
494
|
+
text-orange-600
|
|
495
|
+
>
|
|
496
|
+
{{ countFilesForInput(input.name) }}
|
|
497
|
+
</span>
|
|
498
|
+
<TelaTooltip content="Anexar arquivo" side="top">
|
|
499
|
+
<TelaIconButton
|
|
500
|
+
icon="i-ph-paperclip"
|
|
501
|
+
size="sm"
|
|
502
|
+
color="secondary"
|
|
503
|
+
class="rounded-8px! p-4px!"
|
|
504
|
+
icon-class="text-gray-400 text-16px"
|
|
505
|
+
:disabled="isLocked || pendingFiles.length >= MAX_FILES"
|
|
506
|
+
@click.stop="openFileDialog(input.name)"
|
|
507
|
+
/>
|
|
508
|
+
</TelaTooltip>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
</Transition>
|
|
512
|
+
</div>
|
|
513
|
+
</Transition>
|
|
514
|
+
|
|
294
515
|
<div v-if="pendingFiles.length > 0" flex flex-wrap gap-8px mb-12px>
|
|
295
516
|
<div
|
|
296
|
-
v-for="
|
|
297
|
-
:key="
|
|
298
|
-
flex items-center gap-8px
|
|
517
|
+
v-for="pendingFile in pendingFiles"
|
|
518
|
+
:key="pendingFile.id"
|
|
519
|
+
flex items-center gap-8px flex-wrap
|
|
299
520
|
px-12px py-8px
|
|
300
521
|
rounded-8px
|
|
301
522
|
bg-gray-100
|
|
@@ -303,9 +524,28 @@ defineExpose({
|
|
|
303
524
|
>
|
|
304
525
|
<div i-ph-file text-gray-600 text-16px />
|
|
305
526
|
<div flex="~ col" gap-2px>
|
|
306
|
-
<span body-12-medium text-black-700 max-w-150px truncate>{{ file.name }}</span>
|
|
307
|
-
<span body-11-regular text-gray-500>{{ formatFileSize(file.size) }}</span>
|
|
527
|
+
<span body-12-medium text-black-700 max-w-150px truncate>{{ pendingFile.file.name }}</span>
|
|
528
|
+
<span body-11-regular text-gray-500>{{ formatFileSize(pendingFile.file.size) }}</span>
|
|
308
529
|
</div>
|
|
530
|
+
<select
|
|
531
|
+
v-if="fileInputVariables.length > 0"
|
|
532
|
+
class="agent-file-variable-select"
|
|
533
|
+
:value="pendingFile.inputName ?? ''"
|
|
534
|
+
:disabled="isLocked"
|
|
535
|
+
@change="updatePendingFileInput(pendingFile.id, $event)"
|
|
536
|
+
@click.stop
|
|
537
|
+
>
|
|
538
|
+
<option value="" disabled>
|
|
539
|
+
Selecionar variável
|
|
540
|
+
</option>
|
|
541
|
+
<option
|
|
542
|
+
v-for="input in fileInputVariables"
|
|
543
|
+
:key="input.id || input.name"
|
|
544
|
+
:value="input.name"
|
|
545
|
+
>
|
|
546
|
+
{{ input.name }}
|
|
547
|
+
</option>
|
|
548
|
+
</select>
|
|
309
549
|
<TelaIconButton
|
|
310
550
|
p-4px
|
|
311
551
|
icon="i-ph-x"
|
|
@@ -314,11 +554,15 @@ defineExpose({
|
|
|
314
554
|
hover:bg-gray-200
|
|
315
555
|
transition
|
|
316
556
|
icon-class="text-gray-500 text-12px"
|
|
317
|
-
@click="removeFile(
|
|
557
|
+
@click="removeFile(pendingFile.id)"
|
|
318
558
|
/>
|
|
319
559
|
</div>
|
|
320
560
|
</div>
|
|
321
561
|
|
|
562
|
+
<div v-if="hasUnmappedAgentFiles" text-orange-600 body-12-regular mb-8px>
|
|
563
|
+
Selecione uma variável para cada arquivo anexado.
|
|
564
|
+
</div>
|
|
565
|
+
|
|
322
566
|
<div v-if="uploadError" text-red-600 body-12-regular mb-8px>
|
|
323
567
|
{{ uploadError }}
|
|
324
568
|
</div>
|
|
@@ -424,5 +668,5 @@ defineExpose({
|
|
|
424
668
|
</template>
|
|
425
669
|
|
|
426
670
|
<style scoped>
|
|
427
|
-
.input-container{border:.5px solid #e5e7eb;box-shadow:0 3px 10px 0 hsla(0,0%,64%,.08),0 12px 20px 0 hsla(0,0%,64%,.06)}.input-locked{background:var(--Base-Gray-gray-100,#f3f4f6);border:.5px solid var(--Base-Neutral-neutral-300,#d9d9d9);box-shadow:0 12px 20px 0 hsla(0,0%,64%,.06)}.editor-content{caret-color:#111827;color:#111827;max-height:200px;outline:none;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.editor-content.is-empty:before{color:#bdc4cc;content:attr(data-placeholder);float:left;height:0;pointer-events:none}.icon-button:disabled{cursor:not-allowed;opacity:.5}.custom-scrollbar{scrollbar-color:#d1d5db transparent;scrollbar-width:thin}.custom-scrollbar::-webkit-scrollbar{width:6px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:3px}.stop-button{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;position:relative;transition:opacity .15s ease;width:32px}.stop-button:hover{opacity:.8}.stop-button-ring{border:2px solid #e5e7eb;border-radius:50%;inset:0;position:absolute}.stop-button-ring:before{animation:spin 1s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#111827;content:"";inset:-2px;position:absolute}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}
|
|
671
|
+
.input-container{border:.5px solid #e5e7eb;box-shadow:0 3px 10px 0 hsla(0,0%,64%,.08),0 12px 20px 0 hsla(0,0%,64%,.06);position:relative;z-index:2}.input-locked{background:var(--Base-Gray-gray-100,#f3f4f6);border:.5px solid var(--Base-Neutral-neutral-300,#d9d9d9);box-shadow:0 12px 20px 0 hsla(0,0%,64%,.06)}.agent-inputs-panel{box-shadow:0 3px 10px 0 hsla(0,0%,64%,.06);position:relative;transform-origin:bottom center;will-change:max-height,opacity,transform,filter;z-index:1}.agent-inputs-panel-motion-enter-active,.agent-inputs-panel-motion-leave-active{overflow:hidden;transition:max-height .26s cubic-bezier(.2,.8,.2,1),opacity .18s ease,transform .26s cubic-bezier(.2,.8,.2,1),filter .22s ease}.agent-inputs-panel-motion-enter-from,.agent-inputs-panel-motion-leave-to{filter:blur(2px);max-height:0;opacity:0;transform:translateY(46px) scale(.985)}.agent-inputs-panel-motion-enter-to,.agent-inputs-panel-motion-leave-from{filter:blur(0);max-height:560px;opacity:1;transform:translateY(0) scale(1)}.agent-inputs-content{transform-origin:bottom center;will-change:max-height,opacity,transform,filter}.agent-inputs-content-enter-active,.agent-inputs-content-leave-active{overflow:hidden;transition:max-height .22s cubic-bezier(.2,.8,.2,1),opacity .16s ease,transform .22s cubic-bezier(.2,.8,.2,1),filter .22s ease}.agent-inputs-content-enter-from,.agent-inputs-content-leave-to{filter:blur(2px);max-height:0;opacity:0;transform:translateY(14px) scale(.985)}.agent-inputs-content-enter-to,.agent-inputs-content-leave-from{filter:blur(0);max-height:900px;opacity:1;transform:translateY(0) scale(1)}.agent-text-input{border:.5px solid #e5e7eb;border-radius:8px;color:#111827;font-size:13px;line-height:18px;min-height:64px;outline:none;padding:8px 10px;resize:vertical;width:100%}.agent-text-input:focus{border-color:#d1d5db}.agent-text-input:disabled{background-color:#f3f4f6;cursor:not-allowed}.agent-file-variable-select{background:#fff;border:.5px solid #d1d5db;border-radius:6px;color:#374151;font-size:12px;height:28px;max-width:160px;outline:none;padding:0 8px}.editor-content{caret-color:#111827;color:#111827;max-height:200px;outline:none;overflow-y:auto;white-space:pre-wrap;word-break:break-word}.editor-content.is-empty:before{color:#bdc4cc;content:attr(data-placeholder);float:left;height:0;pointer-events:none}.icon-button:disabled{cursor:not-allowed;opacity:.5}.custom-scrollbar{scrollbar-color:#d1d5db transparent;scrollbar-width:thin}.custom-scrollbar::-webkit-scrollbar{width:6px}.custom-scrollbar::-webkit-scrollbar-track{background:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{background-color:#d1d5db;border-radius:3px}.stop-button{align-items:center;background:transparent;border:none;cursor:pointer;display:flex;height:32px;justify-content:center;padding:0;position:relative;transition:opacity .15s ease;width:32px}.stop-button:hover{opacity:.8}.stop-button-ring{border:2px solid #e5e7eb;border-radius:50%;inset:0;position:absolute}.stop-button-ring:before{animation:spin 1s linear infinite;border:2px solid transparent;border-radius:50%;border-top-color:#111827;content:"";inset:-2px;position:absolute}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}
|
|
428
672
|
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ConversationFile, FileUploadInput, Message, ModelOption } from '../../types/chat.js';
|
|
2
2
|
import type { DeepReadonly } from 'vue';
|
|
3
|
-
import type { WorkspaceSettings } from '../../
|
|
3
|
+
import type { WorkspaceSettings } from '../../types/workspace-settings-data.js';
|
|
4
|
+
import type { TelaAgentInputVariable } from '../../types/tela-agent.js';
|
|
4
5
|
type __VLS_Props = {
|
|
5
6
|
disabled?: boolean;
|
|
6
7
|
loading?: boolean;
|
|
@@ -12,8 +13,13 @@ type __VLS_Props = {
|
|
|
12
13
|
messages?: Message[];
|
|
13
14
|
conversationFiles?: ConversationFile[];
|
|
14
15
|
workspaceSettings?: DeepReadonly<WorkspaceSettings> | null;
|
|
16
|
+
allowModelSelection?: boolean;
|
|
17
|
+
agentInputSchema?: DeepReadonly<TelaAgentInputVariable[]> | null;
|
|
18
|
+
agentInputSchemaLoading?: boolean;
|
|
19
|
+
showModelSelector?: boolean;
|
|
20
|
+
showCancelButton?: boolean;
|
|
15
21
|
};
|
|
16
|
-
declare function addFiles(files: File[]): void;
|
|
22
|
+
declare function addFiles(files: File[], inputName?: string): void;
|
|
17
23
|
type __VLS_ModelProps = {
|
|
18
24
|
'model'?: ModelOption;
|
|
19
25
|
};
|
|
@@ -24,10 +30,30 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
24
30
|
"update:model": (value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any;
|
|
25
31
|
} & {
|
|
26
32
|
cancel: () => any;
|
|
27
|
-
send: (content: string, files: FileUploadInput[], model
|
|
33
|
+
send: (content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
|
|
34
|
+
type: "file";
|
|
35
|
+
name: string;
|
|
36
|
+
vaultRef: string;
|
|
37
|
+
filename: string;
|
|
38
|
+
metadata?: string | undefined;
|
|
39
|
+
} | {
|
|
40
|
+
type: "text";
|
|
41
|
+
name: string;
|
|
42
|
+
content: string;
|
|
43
|
+
})[] | undefined) => any;
|
|
28
44
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
29
45
|
onCancel?: (() => any) | undefined;
|
|
30
|
-
onSend?: ((content: string, files: FileUploadInput[], model
|
|
46
|
+
onSend?: ((content: string, files: FileUploadInput[], model?: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6" | undefined, agentInputs?: ({
|
|
47
|
+
type: "file";
|
|
48
|
+
name: string;
|
|
49
|
+
vaultRef: string;
|
|
50
|
+
filename: string;
|
|
51
|
+
metadata?: string | undefined;
|
|
52
|
+
} | {
|
|
53
|
+
type: "text";
|
|
54
|
+
name: string;
|
|
55
|
+
content: string;
|
|
56
|
+
})[] | undefined) => any) | undefined;
|
|
31
57
|
"onUpdate:model"?: ((value: "claude-sonnet-4-5" | "claude-sonnet-4-6" | "claude-haiku-4-5" | "claude-opus-4-5" | "claude-opus-4-6") => any) | undefined;
|
|
32
58
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
33
59
|
declare const _default: typeof __VLS_export;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { Conversation, ConversationWithMessages, Message } from '../types/chat.js';
|
|
1
|
+
import type { Conversation, ConversationWithMessages, FileUploadInput, Message } from '../types/chat.js';
|
|
2
|
+
import type { TelaAgentExecutionInput } from '../types/tela-agent.js';
|
|
2
3
|
export declare function useChat(): {
|
|
3
4
|
currentConversation: any;
|
|
4
5
|
messages: any;
|
|
@@ -12,10 +13,7 @@ export declare function useChat(): {
|
|
|
12
13
|
animatedTitle: any;
|
|
13
14
|
loadConversation: (id: string) => Promise<void>;
|
|
14
15
|
setConversation: (conv: Conversation | ConversationWithMessages) => void;
|
|
15
|
-
sendMessage: (content: string, files?:
|
|
16
|
-
url: string;
|
|
17
|
-
name: string;
|
|
18
|
-
}[], model?: string) => Promise<Message | null>;
|
|
16
|
+
sendMessage: (content: string, files?: FileUploadInput[], model?: string, agentInputs?: TelaAgentExecutionInput[]) => Promise<Message | null>;
|
|
19
17
|
retryMessage: (messageId: string) => Promise<boolean>;
|
|
20
18
|
cancelConversation: () => Promise<boolean>;
|
|
21
19
|
startPolling: any;
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import * as Sentry from "@sentry/nuxt";
|
|
2
2
|
import { exportConversationToMarkdown } from "../utils/export-conversation.js";
|
|
3
|
+
import { resolveChatStateScope } from "../utils/tela-chat.js";
|
|
3
4
|
import { useConversationFileActions } from "./useConversationFiles.js";
|
|
5
|
+
function resolveTelaAgentInputs(messageInputs, configuredInputs) {
|
|
6
|
+
const inputs = messageInputs ?? configuredInputs ?? void 0;
|
|
7
|
+
return inputs?.length ? inputs : void 0;
|
|
8
|
+
}
|
|
4
9
|
function getStepKey(step) {
|
|
5
10
|
if (typeof step === "string") {
|
|
6
11
|
return `text:${step.slice(0, 100)}`;
|
|
@@ -147,7 +152,11 @@ export function useChat() {
|
|
|
147
152
|
const embedConfig = useEmbedConfig();
|
|
148
153
|
const { user: authUser, activeOrganization } = useTelaApplicationAuth();
|
|
149
154
|
const { addFilesToConversation } = useConversationFileActions();
|
|
150
|
-
const
|
|
155
|
+
const isTelaAgentMode = computed(() => !!embedConfig?.telaAgentId.value);
|
|
156
|
+
const chatScope = computed(() => resolveChatStateScope(
|
|
157
|
+
embedConfig?.workspaceId.value || activeOrganization.value?.id,
|
|
158
|
+
embedConfig?.telaAgentId.value
|
|
159
|
+
));
|
|
151
160
|
const currentConversationBuckets = useState("chat-current-conversation", () => ({}));
|
|
152
161
|
const messageBuckets = useState("chat-messages", () => ({}));
|
|
153
162
|
const currentConversation = computed({
|
|
@@ -271,7 +280,7 @@ export function useChat() {
|
|
|
271
280
|
loading.value = false;
|
|
272
281
|
}
|
|
273
282
|
};
|
|
274
|
-
const sendMessage = async (content, files, model) => {
|
|
283
|
+
const sendMessage = async (content, files, model, agentInputs) => {
|
|
275
284
|
if (!currentConversation.value)
|
|
276
285
|
return null;
|
|
277
286
|
sending.value = true;
|
|
@@ -307,11 +316,23 @@ export function useChat() {
|
|
|
307
316
|
};
|
|
308
317
|
messages.value = [...messages.value, optimisticUserMessage, optimisticAssistantMessage];
|
|
309
318
|
try {
|
|
319
|
+
const workspaceSettingsSnapshot = embedConfig?.workspaceSettings.value;
|
|
320
|
+
const resolvedAgentInputs = resolveTelaAgentInputs(agentInputs, embedConfig?.telaAgentInputs?.value);
|
|
321
|
+
const body = {
|
|
322
|
+
content,
|
|
323
|
+
files,
|
|
324
|
+
...isTelaAgentMode.value ? {
|
|
325
|
+
...resolvedAgentInputs ? { agentInputs: resolvedAgentInputs } : {}
|
|
326
|
+
} : {
|
|
327
|
+
model,
|
|
328
|
+
...workspaceSettingsSnapshot !== void 0 ? { workspaceSettingsSnapshot } : {}
|
|
329
|
+
}
|
|
330
|
+
};
|
|
310
331
|
const response = await $fetch(
|
|
311
332
|
chatApi.path(`/conversations/${currentConversation.value.id}/messages`),
|
|
312
333
|
chatApi.withChatHeaders({
|
|
313
334
|
method: "POST",
|
|
314
|
-
body
|
|
335
|
+
body
|
|
315
336
|
})
|
|
316
337
|
);
|
|
317
338
|
messages.value = messages.value.map((msg) => {
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type ChatActionPayload = {
|
|
2
|
+
name: string;
|
|
3
|
+
data: unknown;
|
|
4
|
+
messageId?: string;
|
|
5
|
+
};
|
|
6
|
+
export type ChatActionHandler = (payload: ChatActionPayload) => void;
|
|
7
|
+
export declare function provideChatAction(handler: ChatActionHandler): void;
|
|
8
|
+
export declare function useChatAction(): {
|
|
9
|
+
emit(name: string, data?: unknown, messageId?: string): void;
|
|
10
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const CHAT_ACTION_KEY = Symbol("chat-nuxt:action");
|
|
2
|
+
export function provideChatAction(handler) {
|
|
3
|
+
provide(CHAT_ACTION_KEY, handler);
|
|
4
|
+
}
|
|
5
|
+
export function useChatAction() {
|
|
6
|
+
const handler = inject(CHAT_ACTION_KEY, null);
|
|
7
|
+
return {
|
|
8
|
+
emit(name, data, messageId) {
|
|
9
|
+
handler?.({ name, data, messageId });
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
}
|
|
@@ -9,6 +9,10 @@ export function useChatApi() {
|
|
|
9
9
|
if (workspaceId) {
|
|
10
10
|
mergedHeaders["x-chat-workspace-id"] = workspaceId;
|
|
11
11
|
}
|
|
12
|
+
const telaAgentId = embedConfig?.telaAgentId.value;
|
|
13
|
+
if (telaAgentId) {
|
|
14
|
+
mergedHeaders["x-chat-tela-agent-id"] = telaAgentId;
|
|
15
|
+
}
|
|
12
16
|
return Object.keys(mergedHeaders).length > 0 ? mergedHeaders : void 0;
|
|
13
17
|
}
|
|
14
18
|
function withChatHeaders(options) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as Sentry from "@sentry/nuxt";
|
|
2
|
+
import { resolveChatStateScope } from "../utils/tela-chat.js";
|
|
2
3
|
function sortConversationsByUpdatedAt(conversations) {
|
|
3
4
|
return [...conversations].sort(
|
|
4
5
|
(a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
|
@@ -33,7 +34,11 @@ export function useConversations() {
|
|
|
33
34
|
const mutationVersionBuckets = useState("conversations-mutation-version", () => ({}));
|
|
34
35
|
const deletedIdBuckets = useState("conversations-deleted-ids", () => ({}));
|
|
35
36
|
const mutatedIdBuckets = useState("conversations-mutated-ids", () => ({}));
|
|
36
|
-
const
|
|
37
|
+
const isTelaAgentMode = computed(() => !!embedConfig?.telaAgentId.value);
|
|
38
|
+
const workspaceScope = computed(() => resolveChatStateScope(
|
|
39
|
+
embedConfig?.workspaceId.value || activeOrganization.value?.id,
|
|
40
|
+
embedConfig?.telaAgentId.value
|
|
41
|
+
));
|
|
37
42
|
const conversations = computed({
|
|
38
43
|
get: () => conversationBuckets.value[workspaceScope.value] ?? [],
|
|
39
44
|
set: (value) => {
|
|
@@ -166,7 +171,7 @@ export function useConversations() {
|
|
|
166
171
|
chatApi.path("/conversations"),
|
|
167
172
|
chatApi.withChatHeaders({
|
|
168
173
|
method: "POST",
|
|
169
|
-
body: options?.model ? { model: options.model } : void 0
|
|
174
|
+
body: !isTelaAgentMode.value && options?.model ? { model: options.model } : void 0
|
|
170
175
|
})
|
|
171
176
|
);
|
|
172
177
|
commitConversations([conversation, ...conversations.value], conversation.id);
|
|
@@ -222,6 +227,7 @@ export function useConversations() {
|
|
|
222
227
|
model: updated.model,
|
|
223
228
|
appliedSettingsAt: updated.appliedSettingsAt,
|
|
224
229
|
appliedSettingsSnapshot: cloneAppliedSettingsSnapshot(updated.appliedSettingsSnapshot),
|
|
230
|
+
telaAgentId: updated.telaAgentId,
|
|
225
231
|
createdBy: updated.createdBy,
|
|
226
232
|
createdAt: updated.createdAt,
|
|
227
233
|
updatedAt: updated.updatedAt
|
|
@@ -1,19 +1,29 @@
|
|
|
1
|
-
import type { DeepReadonly, MaybeRefOrGetter, Ref } from 'vue';
|
|
1
|
+
import type { Component, DeepReadonly, MaybeRefOrGetter, Ref } from 'vue';
|
|
2
|
+
import type { TelaAgentExecutionInput } from '../types/tela-agent.js';
|
|
3
|
+
import type { WorkspaceSettings } from '../types/workspace-settings-data.js';
|
|
2
4
|
import type { ChatLoadingMessageMode } from '../utils/chat-loading-messages.js';
|
|
3
|
-
|
|
5
|
+
type ConfiguredTelaAgentInputs = DeepReadonly<TelaAgentExecutionInput[]> | null | undefined;
|
|
4
6
|
export type EmbedConfig = {
|
|
5
7
|
workspaceId: Ref<string>;
|
|
8
|
+
telaAgentId: Ref<string | null>;
|
|
9
|
+
telaAgentInputs: Ref<ConfiguredTelaAgentInputs>;
|
|
6
10
|
workspaceSettings: Ref<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
7
11
|
hideSidebar: Ref<boolean>;
|
|
8
12
|
loadingMessages: Ref<readonly string[] | null | undefined>;
|
|
9
13
|
loadingMessagesMode: Ref<ChatLoadingMessageMode | null | undefined>;
|
|
14
|
+
customComponents: Ref<Record<string, Component> | undefined>;
|
|
15
|
+
customHtmlTags: Ref<readonly string[] | undefined>;
|
|
10
16
|
};
|
|
11
17
|
type EmbedConfigInput = {
|
|
12
18
|
workspaceId: MaybeRefOrGetter<string>;
|
|
19
|
+
telaAgentId?: MaybeRefOrGetter<string | null | undefined>;
|
|
20
|
+
telaAgentInputs?: MaybeRefOrGetter<ConfiguredTelaAgentInputs>;
|
|
13
21
|
workspaceSettings?: MaybeRefOrGetter<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
14
22
|
hideSidebar?: MaybeRefOrGetter<boolean | undefined>;
|
|
15
23
|
loadingMessages?: MaybeRefOrGetter<readonly string[] | null | undefined>;
|
|
16
24
|
loadingMessagesMode?: MaybeRefOrGetter<ChatLoadingMessageMode | null | undefined>;
|
|
25
|
+
customComponents?: MaybeRefOrGetter<Record<string, Component> | undefined>;
|
|
26
|
+
customHtmlTags?: MaybeRefOrGetter<readonly string[] | undefined>;
|
|
17
27
|
};
|
|
18
28
|
type ProvideEmbedConfigOptions = {
|
|
19
29
|
syncGlobal?: boolean;
|