@meistrari/chat-nuxt 4.5.0-rc.0 → 4.5.0-rc.1
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/dist/module.json +1 -1
- package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +12 -12
- package/dist/runtime/embed/components/chat-embed-inner.vue +11 -0
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +12 -12
- package/dist/runtime/lightweight/messages/composables/chat.d.ts +1 -0
- package/dist/runtime/messages/composables/chat.d.ts +1 -0
- package/dist/runtime/messages/composables/chat.js +48 -13
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -19,29 +19,29 @@ type __VLS_Props = {
|
|
|
19
19
|
user?: EmbedUser | null;
|
|
20
20
|
features?: Partial<ChatFeatureConfig>;
|
|
21
21
|
};
|
|
22
|
-
declare var
|
|
22
|
+
declare var __VLS_14: {}, __VLS_88: {}, __VLS_101: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_113: {}, __VLS_141: {}, __VLS_150: {}, __VLS_214: {}, __VLS_233: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_245: {};
|
|
27
27
|
type __VLS_Slots = {} & {
|
|
28
|
-
'sidebar-bottom'?: (props: typeof
|
|
28
|
+
'sidebar-bottom'?: (props: typeof __VLS_14) => any;
|
|
29
29
|
} & {
|
|
30
|
-
'composer-bottom'?: (props: typeof
|
|
30
|
+
'composer-bottom'?: (props: typeof __VLS_88) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_101) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_113) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_141) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'topbar-leading'?: (props: typeof
|
|
38
|
+
'topbar-leading'?: (props: typeof __VLS_150) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'composer-bottom'?: (props: typeof
|
|
40
|
+
'composer-bottom'?: (props: typeof __VLS_214) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'failed-message-actions'?: (props: typeof
|
|
42
|
+
'failed-message-actions'?: (props: typeof __VLS_233) => any;
|
|
43
43
|
} & {
|
|
44
|
-
'composer-bottom'?: (props: typeof
|
|
44
|
+
'composer-bottom'?: (props: typeof __VLS_245) => any;
|
|
45
45
|
};
|
|
46
46
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
47
47
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -203,6 +203,7 @@ const {
|
|
|
203
203
|
generatingTitle,
|
|
204
204
|
animatedTitle,
|
|
205
205
|
composerLocked,
|
|
206
|
+
isPolling,
|
|
206
207
|
outboundOccupied,
|
|
207
208
|
sessionReady,
|
|
208
209
|
agentSessionRewakeable,
|
|
@@ -221,6 +222,7 @@ const {
|
|
|
221
222
|
retryMessage,
|
|
222
223
|
cancelConversation,
|
|
223
224
|
startPolling,
|
|
225
|
+
reconnect,
|
|
224
226
|
clearConversation,
|
|
225
227
|
error: chatError
|
|
226
228
|
} = createChat({
|
|
@@ -906,6 +908,15 @@ async function handleDelete() {
|
|
|
906
908
|
rounded-8px bg-error text-error p-12px body-14-regular
|
|
907
909
|
>
|
|
908
910
|
{{ chatError }}
|
|
911
|
+
<TelaButton
|
|
912
|
+
v-if="composerLocked && !isPolling"
|
|
913
|
+
variant="ghost-danger"
|
|
914
|
+
size="sm"
|
|
915
|
+
icon="i-ph-arrow-clockwise"
|
|
916
|
+
@click="reconnect"
|
|
917
|
+
>
|
|
918
|
+
Reconectar
|
|
919
|
+
</TelaButton>
|
|
909
920
|
</div>
|
|
910
921
|
<!-- Sidebar -->
|
|
911
922
|
<div
|
|
@@ -19,29 +19,29 @@ type __VLS_Props = {
|
|
|
19
19
|
user?: EmbedUser | null;
|
|
20
20
|
features?: Partial<ChatFeatureConfig>;
|
|
21
21
|
};
|
|
22
|
-
declare var
|
|
22
|
+
declare var __VLS_14: {}, __VLS_88: {}, __VLS_101: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_113: {}, __VLS_141: {}, __VLS_150: {}, __VLS_214: {}, __VLS_233: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_245: {};
|
|
27
27
|
type __VLS_Slots = {} & {
|
|
28
|
-
'sidebar-bottom'?: (props: typeof
|
|
28
|
+
'sidebar-bottom'?: (props: typeof __VLS_14) => any;
|
|
29
29
|
} & {
|
|
30
|
-
'composer-bottom'?: (props: typeof
|
|
30
|
+
'composer-bottom'?: (props: typeof __VLS_88) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_101) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_113) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_141) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'topbar-leading'?: (props: typeof
|
|
38
|
+
'topbar-leading'?: (props: typeof __VLS_150) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'composer-bottom'?: (props: typeof
|
|
40
|
+
'composer-bottom'?: (props: typeof __VLS_214) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'failed-message-actions'?: (props: typeof
|
|
42
|
+
'failed-message-actions'?: (props: typeof __VLS_233) => any;
|
|
43
43
|
} & {
|
|
44
|
-
'composer-bottom'?: (props: typeof
|
|
44
|
+
'composer-bottom'?: (props: typeof __VLS_245) => any;
|
|
45
45
|
};
|
|
46
46
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
47
47
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -35,6 +35,7 @@ export declare function useChat(options?: Parameters<typeof useSharedChat>[0]):
|
|
|
35
35
|
retryMessage: (messageId: string, prepare?: () => Promise<void>) => Promise<boolean>;
|
|
36
36
|
cancelConversation: () => Promise<boolean>;
|
|
37
37
|
startPolling: () => void;
|
|
38
|
+
reconnect: () => void;
|
|
38
39
|
stopPolling: () => void;
|
|
39
40
|
clearConversation: () => void;
|
|
40
41
|
clearConversationThread: () => Promise<boolean>;
|
|
@@ -57,6 +57,7 @@ export declare function useChat(options?: {
|
|
|
57
57
|
retryMessage: (messageId: string, prepare?: () => Promise<void>) => Promise<boolean>;
|
|
58
58
|
cancelConversation: () => Promise<boolean>;
|
|
59
59
|
startPolling: () => void;
|
|
60
|
+
reconnect: () => void;
|
|
60
61
|
stopPolling: () => void;
|
|
61
62
|
clearConversation: () => void;
|
|
62
63
|
clearConversationThread: () => Promise<boolean>;
|
|
@@ -28,6 +28,12 @@ import { usePolling } from "../../shared/composables/polling.js";
|
|
|
28
28
|
import { ChatMessageStatus, terminalMessageTransitions, useChatMessageTerminal } from "./chat-message-terminal.js";
|
|
29
29
|
import { useDirectStream } from "./use-direct-stream.js";
|
|
30
30
|
import { useOutboundQueue } from "./outbound-queue.js";
|
|
31
|
+
const POLL_OUTAGE_NOTICE_FAILURES = 5;
|
|
32
|
+
const POLL_OUTAGE_BUDGET_MS = 6e4;
|
|
33
|
+
const POLL_INTERVAL_MS = 500;
|
|
34
|
+
const POLL_MAX_BACKOFF_MS = 5e3;
|
|
35
|
+
const CHAT_REQUEST_TIMEOUT_MS = 15e3;
|
|
36
|
+
const CHAT_UNAVAILABLE_TEXT = "Chat temporariamente indispon\xEDvel. Tente novamente.";
|
|
31
37
|
const WORKSPACE_AGENT_NOT_READY_TEXT = "O agente deste workspace ainda n\xE3o foi configurado no Tela. Abra as configura\xE7\xF5es do workspace para criar o agente.";
|
|
32
38
|
export function resolveTelaAgentInputs(messageInputs, configuredInputs) {
|
|
33
39
|
const inputs = messageInputs ?? configuredInputs;
|
|
@@ -241,6 +247,9 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
241
247
|
}
|
|
242
248
|
}
|
|
243
249
|
let pollGeneration = 0;
|
|
250
|
+
let consecutivePollFailures = 0;
|
|
251
|
+
let pollOutageStartedAt = null;
|
|
252
|
+
const pollInterval = ref(POLL_INTERVAL_MS);
|
|
244
253
|
const pollMessages = async () => {
|
|
245
254
|
if (!currentConversation.value)
|
|
246
255
|
return;
|
|
@@ -251,14 +260,17 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
251
260
|
try {
|
|
252
261
|
const runtime = chatApi.conversationV2Enabled ? await $fetch(
|
|
253
262
|
chatApi.runtimePath(`/conversations/${conversationId}/runtime`),
|
|
254
|
-
chatApi.withChatHeaders()
|
|
263
|
+
chatApi.withChatHeaders({ timeout: CHAT_REQUEST_TIMEOUT_MS, retry: 0 })
|
|
255
264
|
) : null;
|
|
256
265
|
const response = await $fetch(
|
|
257
266
|
chatApi.path(`/conversations/${conversationId}/messages`),
|
|
258
|
-
chatApi.withChatHeaders()
|
|
267
|
+
chatApi.withChatHeaders({ timeout: CHAT_REQUEST_TIMEOUT_MS, retry: 0 })
|
|
259
268
|
);
|
|
260
269
|
if (generation !== pollGeneration || currentConversation.value?.id !== conversationId)
|
|
261
270
|
return;
|
|
271
|
+
resetPollOutage();
|
|
272
|
+
if (error.value === CHAT_UNAVAILABLE_TEXT)
|
|
273
|
+
error.value = null;
|
|
262
274
|
if (runtime)
|
|
263
275
|
runtimeBlocked.value = runtime.conversation.runtimeState === "blocked";
|
|
264
276
|
if (response.agentSession) {
|
|
@@ -332,16 +344,28 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
332
344
|
Sentry.captureException(err);
|
|
333
345
|
if (generation !== pollGeneration)
|
|
334
346
|
return;
|
|
335
|
-
const
|
|
336
|
-
const
|
|
337
|
-
|
|
347
|
+
const statusCode = getChatApiErrorStatus(err);
|
|
348
|
+
const terminalError = statusCode === 501 || statusCode !== null && statusCode >= 400 && statusCode < 500 && statusCode !== 408 && statusCode !== 429;
|
|
349
|
+
consecutivePollFailures++;
|
|
350
|
+
pollOutageStartedAt ??= Date.now();
|
|
351
|
+
pollInterval.value = Math.min(POLL_INTERVAL_MS * 2 ** consecutivePollFailures, POLL_MAX_BACKOFF_MS);
|
|
352
|
+
if (!terminalError && consecutivePollFailures >= POLL_OUTAGE_NOTICE_FAILURES)
|
|
353
|
+
error.value = CHAT_UNAVAILABLE_TEXT;
|
|
354
|
+
const outageExhausted = Date.now() - pollOutageStartedAt >= POLL_OUTAGE_BUDGET_MS;
|
|
355
|
+
if (terminalError || outageExhausted) {
|
|
356
|
+
const message = statusCode === 501 || !terminalError ? CHAT_UNAVAILABLE_TEXT : getChatApiErrorMessage(err) ?? "Erro ao atualizar mensagens";
|
|
357
|
+
if (!terminalError || statusCode === 501 || outbound.occupied.value) {
|
|
358
|
+
error.value = message;
|
|
359
|
+
stopPolling();
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
338
362
|
const previousMessages = messages.value;
|
|
339
|
-
const failedMessages = markPendingAssistantMessagesFailed(previousMessages).map((
|
|
340
|
-
if (
|
|
341
|
-
return
|
|
363
|
+
const failedMessages = markPendingAssistantMessagesFailed(previousMessages).map((message2) => {
|
|
364
|
+
if (message2.role !== "assistant" || message2.status !== ChatMessageStatus.Completed || !pendingStreamReconciliationIds.value.has(message2.id)) {
|
|
365
|
+
return message2;
|
|
342
366
|
}
|
|
343
367
|
return {
|
|
344
|
-
...
|
|
368
|
+
...message2,
|
|
345
369
|
content: GENERATION_FAILED_TEXT,
|
|
346
370
|
status: ChatMessageStatus.Failed
|
|
347
371
|
};
|
|
@@ -352,20 +376,30 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
352
376
|
messages.value = failedMessages;
|
|
353
377
|
for (const terminalMessage of terminalMessages)
|
|
354
378
|
chatMessageTerminal.emit(terminalMessage);
|
|
355
|
-
error.value =
|
|
379
|
+
error.value = message;
|
|
356
380
|
stopPolling();
|
|
357
381
|
}
|
|
358
382
|
}
|
|
359
383
|
};
|
|
360
384
|
const { isPolling, start: beginPolling, stop: endPolling } = usePolling({
|
|
361
385
|
callback: pollMessages,
|
|
362
|
-
interval:
|
|
386
|
+
interval: pollInterval,
|
|
363
387
|
stopCondition
|
|
364
388
|
});
|
|
389
|
+
function resetPollOutage() {
|
|
390
|
+
consecutivePollFailures = 0;
|
|
391
|
+
pollOutageStartedAt = null;
|
|
392
|
+
pollInterval.value = POLL_INTERVAL_MS;
|
|
393
|
+
}
|
|
365
394
|
function startPolling() {
|
|
395
|
+
resetPollOutage();
|
|
366
396
|
pollGeneration++;
|
|
367
397
|
beginPolling();
|
|
368
398
|
}
|
|
399
|
+
function reconnect() {
|
|
400
|
+
error.value = null;
|
|
401
|
+
startPolling();
|
|
402
|
+
}
|
|
369
403
|
function stopPolling() {
|
|
370
404
|
pollGeneration++;
|
|
371
405
|
endPolling();
|
|
@@ -614,7 +648,7 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
614
648
|
v2AdmissionRequested = true;
|
|
615
649
|
const accepted = await $fetch(
|
|
616
650
|
chatApi.runtimePath(`/conversations/${conversationId2}/messages`),
|
|
617
|
-
chatApi.withChatHeaders({ method: "POST", body: v2Body, retry: 1 })
|
|
651
|
+
chatApi.withChatHeaders({ method: "POST", body: v2Body, retry: 1, timeout: CHAT_REQUEST_TIMEOUT_MS })
|
|
618
652
|
);
|
|
619
653
|
response = accepted;
|
|
620
654
|
if (currentConversation.value?.id !== conversationId2)
|
|
@@ -661,7 +695,7 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
661
695
|
} catch (err) {
|
|
662
696
|
const code = getChatApiErrorCode(err);
|
|
663
697
|
const status = getChatApiErrorStatus(err);
|
|
664
|
-
if (v2AdmissionRequested && !controller.signal.aborted && (status === null || status === 408 || status === 429 || status >= 500)) {
|
|
698
|
+
if (v2AdmissionRequested && !controller.signal.aborted && (status === null || status === 408 || status === 429 || status >= 500 && status !== 501)) {
|
|
665
699
|
const attempts = (queuedSend?.attempts ?? 0) + 1;
|
|
666
700
|
const queuedAt = queuedSend?.queuedAt ?? Date.now();
|
|
667
701
|
if (outboundQueueEnabled.value) {
|
|
@@ -1029,6 +1063,7 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
1029
1063
|
retryMessage,
|
|
1030
1064
|
cancelConversation,
|
|
1031
1065
|
startPolling,
|
|
1066
|
+
reconnect,
|
|
1032
1067
|
stopPolling,
|
|
1033
1068
|
clearConversation,
|
|
1034
1069
|
clearConversationThread,
|