@meistrari/chat-nuxt 3.17.0-rc.5 → 3.17.0-rc.7
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 +5 -1
- package/dist/runtime/embed/components/chat-embed-inner.vue +23 -4
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +5 -1
- package/dist/runtime/embed/components/chat-embed.d.vue.ts +3 -1
- package/dist/runtime/embed/components/chat-embed.vue +3 -0
- package/dist/runtime/embed/components/chat-embed.vue.d.ts +3 -1
- package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +4 -1
- package/dist/runtime/embed/components/meistrari-chat-embed.vue +13 -2
- package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +4 -1
- package/dist/runtime/messages/components/chat-message-bubble.d.vue.ts +13 -1
- package/dist/runtime/messages/components/chat-message-bubble.vue +26 -19
- package/dist/runtime/messages/components/chat-message-bubble.vue.d.ts +13 -1
- package/dist/runtime/messages/components/chat-message-list.d.vue.ts +12 -1
- package/dist/runtime/messages/components/chat-message-list.vue +6 -1
- package/dist/runtime/messages/components/chat-message-list.vue.d.ts +12 -1
- package/dist/runtime/messages/composables/chat.js +118 -30
- package/dist/runtime/messages/composables/use-direct-stream.d.ts +1 -0
- package/dist/runtime/messages/composables/use-direct-stream.js +19 -4
- package/dist/runtime/server/api/v2/conversations/[...path].d.ts +2 -0
- package/dist/runtime/server/api/v2/conversations/[...path].js +2 -0
- package/dist/runtime/server/utils/chat-api-proxy.d.ts +8 -2
- package/dist/runtime/server/utils/chat-api-proxy.js +21 -8
- package/dist/runtime/shared/composables/chat-api.d.ts +2 -0
- package/dist/runtime/shared/composables/chat-api.js +2 -0
- package/dist/runtime/types/embed.d.ts +1 -1
- package/dist/runtime/types/schemas/chat/chat-config.d.ts +1 -0
- package/dist/runtime/types/schemas/chat/chat-config.js +1 -0
- package/dist/runtime/types/schemas/chat/conversation-runtime.d.ts +239 -0
- package/dist/runtime/types/schemas/chat/conversation-runtime.js +69 -0
- package/package.json +3 -1
package/dist/module.json
CHANGED
|
@@ -15,9 +15,13 @@ type __VLS_Props = {
|
|
|
15
15
|
user?: EmbedUser | null;
|
|
16
16
|
features?: Partial<ChatFeatureConfig>;
|
|
17
17
|
};
|
|
18
|
-
declare var __VLS_11: {};
|
|
18
|
+
declare var __VLS_11: {}, __VLS_94: any, __VLS_200: any;
|
|
19
19
|
type __VLS_Slots = {} & {
|
|
20
20
|
'sidebar-bottom'?: (props: typeof __VLS_11) => any;
|
|
21
|
+
} & {
|
|
22
|
+
'failed-message-actions'?: (props: typeof __VLS_94) => any;
|
|
23
|
+
} & {
|
|
24
|
+
'failed-message-actions'?: (props: typeof __VLS_200) => any;
|
|
21
25
|
};
|
|
22
26
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
23
27
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -219,7 +219,7 @@ function persistConversationModel(conversation, value, wakeAgent) {
|
|
|
219
219
|
const update = updateConversationModel(conversation.id, value).then(async (updated) => {
|
|
220
220
|
if (!updated && currentConversation.value?.id === conversation.id && currentConversation.value.model === value) {
|
|
221
221
|
setConversationModel(previousModel);
|
|
222
|
-
} else if (updated && value && wakeAgent) {
|
|
222
|
+
} else if (updated && value && wakeAgent && !chatApi.conversationV2Enabled) {
|
|
223
223
|
if (conversation.threadSessionId)
|
|
224
224
|
await agentWake.ensureReady(conversation.threadSessionId, value);
|
|
225
225
|
else
|
|
@@ -325,6 +325,10 @@ function updateConversationId(nextConversationId) {
|
|
|
325
325
|
}
|
|
326
326
|
async function ensureConversationLoaded(conversationId) {
|
|
327
327
|
if (currentConversation.value?.id === conversationId) {
|
|
328
|
+
if (chatApi.conversationV2Enabled) {
|
|
329
|
+
startPolling();
|
|
330
|
+
return;
|
|
331
|
+
}
|
|
328
332
|
if (currentConversation.value.threadSessionId)
|
|
329
333
|
void agentWake.ensureReady(currentConversation.value.threadSessionId, selectedModel.value);
|
|
330
334
|
else
|
|
@@ -346,6 +350,10 @@ async function ensureConversationLoaded(conversationId) {
|
|
|
346
350
|
});
|
|
347
351
|
return;
|
|
348
352
|
}
|
|
353
|
+
if (chatApi.conversationV2Enabled) {
|
|
354
|
+
startPolling();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
349
357
|
if (currentConversation.value.threadSessionId)
|
|
350
358
|
void agentWake.ensureReady(currentConversation.value.threadSessionId, selectedModel.value);
|
|
351
359
|
else
|
|
@@ -360,7 +368,8 @@ async function ensureConversationLoaded(conversationId) {
|
|
|
360
368
|
function resetConversation(shouldEmit = true) {
|
|
361
369
|
clearConversation();
|
|
362
370
|
agentWake.consume();
|
|
363
|
-
|
|
371
|
+
if (!chatApi.conversationV2Enabled)
|
|
372
|
+
void agentWake.wake(void 0, selectedModel.value);
|
|
364
373
|
activeTab.value = "chat";
|
|
365
374
|
closeFilesPanel();
|
|
366
375
|
closePreview();
|
|
@@ -549,6 +558,8 @@ async function handleSend(content, files, agentInputs) {
|
|
|
549
558
|
selectedModel.value,
|
|
550
559
|
(value) => persistConversationModel(conversation, value, false)
|
|
551
560
|
);
|
|
561
|
+
if (chatApi.conversationV2Enabled)
|
|
562
|
+
return {};
|
|
552
563
|
if (conversation.threadSessionId && resolvedFeatures.value.chatOutboundQueue) {
|
|
553
564
|
const wake = await agentWake.ensureReady(conversation.threadSessionId, selectedModel.value);
|
|
554
565
|
if (wake.status !== "ready") {
|
|
@@ -1023,7 +1034,11 @@ async function handleDelete() {
|
|
|
1023
1034
|
:show-ttft="resolvedFeatures.showTtft"
|
|
1024
1035
|
variant="mobile"
|
|
1025
1036
|
@retry="handleRetry"
|
|
1026
|
-
|
|
1037
|
+
>
|
|
1038
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
1039
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
1040
|
+
</template>
|
|
1041
|
+
</ChatMessageList>
|
|
1027
1042
|
<ChatMessageInput
|
|
1028
1043
|
ref="messageInputRef"
|
|
1029
1044
|
v-model:selected-model="selectedModel"
|
|
@@ -1229,7 +1244,11 @@ async function handleDelete() {
|
|
|
1229
1244
|
:show-ttft="resolvedFeatures.showTtft"
|
|
1230
1245
|
:variant="compact ? 'widget' : 'page'"
|
|
1231
1246
|
@retry="handleRetry"
|
|
1232
|
-
|
|
1247
|
+
>
|
|
1248
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
1249
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
1250
|
+
</template>
|
|
1251
|
+
</ChatMessageList>
|
|
1233
1252
|
<ChatMessageInput
|
|
1234
1253
|
ref="messageInputRef"
|
|
1235
1254
|
v-model:selected-model="selectedModel"
|
|
@@ -15,9 +15,13 @@ type __VLS_Props = {
|
|
|
15
15
|
user?: EmbedUser | null;
|
|
16
16
|
features?: Partial<ChatFeatureConfig>;
|
|
17
17
|
};
|
|
18
|
-
declare var __VLS_11: {};
|
|
18
|
+
declare var __VLS_11: {}, __VLS_94: any, __VLS_200: any;
|
|
19
19
|
type __VLS_Slots = {} & {
|
|
20
20
|
'sidebar-bottom'?: (props: typeof __VLS_11) => any;
|
|
21
|
+
} & {
|
|
22
|
+
'failed-message-actions'?: (props: typeof __VLS_94) => any;
|
|
23
|
+
} & {
|
|
24
|
+
'failed-message-actions'?: (props: typeof __VLS_200) => any;
|
|
21
25
|
};
|
|
22
26
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
23
27
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -2,9 +2,11 @@ import { useChatAuth } from '#chat-auth';
|
|
|
2
2
|
import { type ChatActionPayload } from '../../messages/composables/chat-action.js';
|
|
3
3
|
import { type MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import { type ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
|
-
declare var __VLS_13: {};
|
|
5
|
+
declare var __VLS_13: {}, __VLS_16: any;
|
|
6
6
|
type __VLS_Slots = {} & {
|
|
7
7
|
'sidebar-bottom'?: (props: typeof __VLS_13) => any;
|
|
8
|
+
} & {
|
|
9
|
+
'failed-message-actions'?: (props: typeof __VLS_16) => any;
|
|
8
10
|
};
|
|
9
11
|
declare const __VLS_base: import("vue").DefineComponent<(import("../types.js").ChatEmbedSharedProps & {
|
|
10
12
|
telaAgentId?: undefined;
|
|
@@ -131,5 +131,8 @@ provideChatMessageTerminal((payload) => {
|
|
|
131
131
|
<template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
|
|
132
132
|
<slot name="sidebar-bottom" />
|
|
133
133
|
</template>
|
|
134
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
135
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
136
|
+
</template>
|
|
134
137
|
</ChatEmbedInner>
|
|
135
138
|
</template>
|
|
@@ -2,9 +2,11 @@ import { useChatAuth } from '#chat-auth';
|
|
|
2
2
|
import { type ChatActionPayload } from '../../messages/composables/chat-action.js';
|
|
3
3
|
import { type MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import { type ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
|
-
declare var __VLS_13: {};
|
|
5
|
+
declare var __VLS_13: {}, __VLS_16: any;
|
|
6
6
|
type __VLS_Slots = {} & {
|
|
7
7
|
'sidebar-bottom'?: (props: typeof __VLS_13) => any;
|
|
8
|
+
} & {
|
|
9
|
+
'failed-message-actions'?: (props: typeof __VLS_16) => any;
|
|
8
10
|
};
|
|
9
11
|
declare const __VLS_base: import("vue").DefineComponent<(import("../types.js").ChatEmbedSharedProps & {
|
|
10
12
|
telaAgentId?: undefined;
|
|
@@ -2,6 +2,7 @@ import type { DefineSetupFnComponent, SlotsType } from 'vue';
|
|
|
2
2
|
import type { ChatActionPayload } from '../../messages/composables/chat-action.js';
|
|
3
3
|
import type { MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import type { ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
|
+
import type { Message } from '../../types/schemas/chat/conversations.js';
|
|
5
6
|
import type { ChatFeatureConfig } from '../feature-config.js';
|
|
6
7
|
import type { AvailableChatModels, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
7
8
|
|
|
@@ -23,6 +24,8 @@ type MeistrariChatEmbedEmits = {
|
|
|
23
24
|
type MeistrariChatEmbedSlots = SlotsType<{
|
|
24
25
|
/** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. Page variant only. */
|
|
25
26
|
'sidebar-bottom'?: () => any;
|
|
27
|
+
/** Rendered inside a failed assistant message's error box, next to "Tentar novamente"; receives the failed message. */
|
|
28
|
+
'failed-message-actions'?: (props: { message: Message }) => any;
|
|
26
29
|
}>;
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -54,4 +57,4 @@ type MeistrariChatEmbedSlots = SlotsType<{
|
|
|
54
57
|
declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
|
|
55
58
|
|
|
56
59
|
export default MeistrariChatEmbed;
|
|
57
|
-
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
60
|
+
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, Message, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
@@ -109,6 +109,9 @@ const widgetEmbedProps = computed(() => ({
|
|
|
109
109
|
<template v-if="$slots['sidebar-bottom']" #sidebar-bottom>
|
|
110
110
|
<slot name="sidebar-bottom" />
|
|
111
111
|
</template>
|
|
112
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
113
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
114
|
+
</template>
|
|
112
115
|
</ChatEmbed>
|
|
113
116
|
|
|
114
117
|
<ClientOnly v-else>
|
|
@@ -138,7 +141,11 @@ const widgetEmbedProps = computed(() => ({
|
|
|
138
141
|
@action="emit('action', $event)"
|
|
139
142
|
@message-feedback="emit('messageFeedback', $event)"
|
|
140
143
|
@message-terminal="emit('messageTerminal', $event)"
|
|
141
|
-
|
|
144
|
+
>
|
|
145
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
146
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
147
|
+
</template>
|
|
148
|
+
</ChatEmbed>
|
|
142
149
|
</div>
|
|
143
150
|
</TelaChatFloatingWindow>
|
|
144
151
|
|
|
@@ -163,7 +170,11 @@ const widgetEmbedProps = computed(() => ({
|
|
|
163
170
|
@action="emit('action', $event)"
|
|
164
171
|
@message-feedback="emit('messageFeedback', $event)"
|
|
165
172
|
@message-terminal="emit('messageTerminal', $event)"
|
|
166
|
-
|
|
173
|
+
>
|
|
174
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
175
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
176
|
+
</template>
|
|
177
|
+
</ChatEmbed>
|
|
167
178
|
</div>
|
|
168
179
|
</TelaChatSidepanelWindow>
|
|
169
180
|
</ClientOnly>
|
|
@@ -2,6 +2,7 @@ import type { DefineSetupFnComponent, SlotsType } from 'vue';
|
|
|
2
2
|
import type { ChatActionPayload } from '../../messages/composables/chat-action.js';
|
|
3
3
|
import type { MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import type { ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
|
+
import type { Message } from '../../types/schemas/chat/conversations.js';
|
|
5
6
|
import type { ChatFeatureConfig } from '../feature-config.js';
|
|
6
7
|
import type { AvailableChatModels, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
7
8
|
|
|
@@ -23,6 +24,8 @@ type MeistrariChatEmbedEmits = {
|
|
|
23
24
|
type MeistrariChatEmbedSlots = SlotsType<{
|
|
24
25
|
/** Rendered in a dedicated bottom pane of the conversation sidebar, splitting it in half. Page variant only. */
|
|
25
26
|
'sidebar-bottom'?: () => any;
|
|
27
|
+
/** Rendered inside a failed assistant message's error box, next to "Tentar novamente"; receives the failed message. */
|
|
28
|
+
'failed-message-actions'?: (props: { message: Message }) => any;
|
|
26
29
|
}>;
|
|
27
30
|
|
|
28
31
|
/**
|
|
@@ -54,4 +57,4 @@ type MeistrariChatEmbedSlots = SlotsType<{
|
|
|
54
57
|
declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
|
|
55
58
|
|
|
56
59
|
export default MeistrariChatEmbed;
|
|
57
|
-
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
60
|
+
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, Message, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
@@ -9,12 +9,24 @@ type __VLS_Props = {
|
|
|
9
9
|
preparingSteps?: readonly string[] | null;
|
|
10
10
|
showTtft?: boolean;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
/** Host actions rendered inside a failed assistant message, next to the retry button. */
|
|
14
|
+
'failed-message-actions'?: (props: {
|
|
15
|
+
message: Message;
|
|
16
|
+
}) => unknown;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
13
19
|
retry: (messageId: string) => any;
|
|
14
20
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
21
|
onRetry?: ((messageId: string) => any) | undefined;
|
|
16
22
|
}>, {
|
|
17
23
|
showTtft: boolean;
|
|
18
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
19
26
|
declare const _default: typeof __VLS_export;
|
|
20
27
|
export default _default;
|
|
28
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
29
|
+
new (): {
|
|
30
|
+
$slots: S;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -13,6 +13,7 @@ const props = defineProps({
|
|
|
13
13
|
showTtft: { type: Boolean, required: false, default: true }
|
|
14
14
|
});
|
|
15
15
|
const emit = defineEmits(["retry"]);
|
|
16
|
+
defineSlots();
|
|
16
17
|
const { user } = useChatAuth();
|
|
17
18
|
const { getMemberByEmail } = useWorkspaceMembers();
|
|
18
19
|
const embedConfig = useEmbedConfig();
|
|
@@ -203,9 +204,14 @@ const hasDetectedFiles = computed(() => contentSegments.value.some((s) => s.type
|
|
|
203
204
|
<span heading-h5-semibold text-primary>{{ isPromptTooLong ? "Limite de contexto atingido" : "Erro" }}</span>
|
|
204
205
|
<span body-10-regular text-secondary>{{ formatTime(message.createdAt) }}</span>
|
|
205
206
|
</div>
|
|
206
|
-
<
|
|
207
|
-
|
|
208
|
-
|
|
207
|
+
<template v-if="isPromptTooLong">
|
|
208
|
+
<div body-12-regular text-secondary whitespace-pre-wrap>
|
|
209
|
+
Esta conversa atingiu o limite de contexto do modelo e não pode continuar. Inicie uma nova conversa para seguir com o assunto.
|
|
210
|
+
</div>
|
|
211
|
+
<div v-if="$slots['failed-message-actions']" mt-8px flex flex-wrap items-center gap-8px>
|
|
212
|
+
<slot name="failed-message-actions" :message="message" />
|
|
213
|
+
</div>
|
|
214
|
+
</template>
|
|
209
215
|
<template v-else>
|
|
210
216
|
<div body-12-regular text-secondary whitespace-pre-wrap>
|
|
211
217
|
{{ displayContent }}
|
|
@@ -213,22 +219,23 @@ const hasDetectedFiles = computed(() => contentSegments.value.some((s) => s.type
|
|
|
213
219
|
<div v-if="message.failReason" body-10-regular text-tertiary whitespace-pre-wrap>
|
|
214
220
|
{{ message.failReason }}
|
|
215
221
|
</div>
|
|
216
|
-
<
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
222
|
+
<div mt-8px flex flex-wrap items-center gap-8px>
|
|
223
|
+
<button
|
|
224
|
+
flex items-center gap-6px
|
|
225
|
+
px-12px py-6px
|
|
226
|
+
rounded-6px
|
|
227
|
+
bg-gray-100
|
|
228
|
+
hover:bg-gray-200
|
|
229
|
+
text-13px text-gray-700
|
|
230
|
+
transition-colors
|
|
231
|
+
cursor-pointer
|
|
232
|
+
@click="emit('retry', message.id)"
|
|
233
|
+
>
|
|
234
|
+
<div i-ph-arrow-clockwise text-14px />
|
|
235
|
+
<span>Tentar novamente</span>
|
|
236
|
+
</button>
|
|
237
|
+
<slot name="failed-message-actions" :message="message" />
|
|
238
|
+
</div>
|
|
232
239
|
</template>
|
|
233
240
|
</div>
|
|
234
241
|
</template>
|
|
@@ -9,12 +9,24 @@ type __VLS_Props = {
|
|
|
9
9
|
preparingSteps?: readonly string[] | null;
|
|
10
10
|
showTtft?: boolean;
|
|
11
11
|
};
|
|
12
|
-
|
|
12
|
+
type __VLS_Slots = {
|
|
13
|
+
/** Host actions rendered inside a failed assistant message, next to the retry button. */
|
|
14
|
+
'failed-message-actions'?: (props: {
|
|
15
|
+
message: Message;
|
|
16
|
+
}) => unknown;
|
|
17
|
+
};
|
|
18
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
13
19
|
retry: (messageId: string) => any;
|
|
14
20
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
21
|
onRetry?: ((messageId: string) => any) | undefined;
|
|
16
22
|
}>, {
|
|
17
23
|
showTtft: boolean;
|
|
18
24
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
25
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
19
26
|
declare const _default: typeof __VLS_export;
|
|
20
27
|
export default _default;
|
|
28
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
29
|
+
new (): {
|
|
30
|
+
$slots: S;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
@@ -13,7 +13,12 @@ type __VLS_Props = {
|
|
|
13
13
|
preparingSteps?: readonly string[] | null;
|
|
14
14
|
showTtft?: boolean;
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
type __VLS_Slots = {
|
|
17
|
+
'failed-message-actions'?: (props: {
|
|
18
|
+
message: Message;
|
|
19
|
+
}) => unknown;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
17
22
|
isPinned: any;
|
|
18
23
|
scrollToBottom: any;
|
|
19
24
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
@@ -23,5 +28,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
23
28
|
}>, {
|
|
24
29
|
showTtft: boolean;
|
|
25
30
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
31
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
32
|
declare const _default: typeof __VLS_export;
|
|
27
33
|
export default _default;
|
|
34
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
35
|
+
new (): {
|
|
36
|
+
$slots: S;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -11,6 +11,7 @@ const props = defineProps({
|
|
|
11
11
|
showTtft: { type: Boolean, required: false, default: true }
|
|
12
12
|
});
|
|
13
13
|
const emit = defineEmits(["retry"]);
|
|
14
|
+
defineSlots();
|
|
14
15
|
const conversationRef = ref(null);
|
|
15
16
|
const conversationElements = computed(() => {
|
|
16
17
|
const root = conversationRef.value?.$el;
|
|
@@ -106,7 +107,11 @@ defineExpose({
|
|
|
106
107
|
:preparing-steps="item.value.role === 'assistant' && item.value.status === 'pending' ? preparingSteps : null"
|
|
107
108
|
:show-ttft="showTtft"
|
|
108
109
|
@retry="emit('retry', $event)"
|
|
109
|
-
|
|
110
|
+
>
|
|
111
|
+
<template v-if="$slots['failed-message-actions']" #failed-message-actions="slotProps">
|
|
112
|
+
<slot name="failed-message-actions" v-bind="slotProps" />
|
|
113
|
+
</template>
|
|
114
|
+
</ChatMessageBubble>
|
|
110
115
|
</template>
|
|
111
116
|
<p
|
|
112
117
|
v-if="messages.length > 0"
|
|
@@ -13,7 +13,12 @@ type __VLS_Props = {
|
|
|
13
13
|
preparingSteps?: readonly string[] | null;
|
|
14
14
|
showTtft?: boolean;
|
|
15
15
|
};
|
|
16
|
-
|
|
16
|
+
type __VLS_Slots = {
|
|
17
|
+
'failed-message-actions'?: (props: {
|
|
18
|
+
message: Message;
|
|
19
|
+
}) => unknown;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {
|
|
17
22
|
isPinned: any;
|
|
18
23
|
scrollToBottom: any;
|
|
19
24
|
}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
@@ -23,5 +28,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {
|
|
|
23
28
|
}>, {
|
|
24
29
|
showTtft: boolean;
|
|
25
30
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
31
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
26
32
|
declare const _default: typeof __VLS_export;
|
|
27
33
|
export default _default;
|
|
34
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
35
|
+
new (): {
|
|
36
|
+
$slots: S;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -42,6 +42,8 @@ export function resolveStreamingContent(authoritative, provisional) {
|
|
|
42
42
|
}
|
|
43
43
|
export function useChat(options = {}) {
|
|
44
44
|
const chatApi = useChatApi();
|
|
45
|
+
const runtimeBlocked = ref(false);
|
|
46
|
+
let streamConnecting = false;
|
|
45
47
|
const chatMessageTerminal = useChatMessageTerminal();
|
|
46
48
|
const embedConfig = useEmbedConfig();
|
|
47
49
|
const { user: authUser, activeOrganization } = useChatAuth();
|
|
@@ -152,7 +154,7 @@ export function useChat(options = {}) {
|
|
|
152
154
|
const pendingStreamReconciliationIds = ref(/* @__PURE__ */ new Set());
|
|
153
155
|
const pendingRealResultIds = ref(/* @__PURE__ */ new Set());
|
|
154
156
|
const composerLocked = computed(
|
|
155
|
-
() => hasPendingMessage.value || pendingRealResultIds.value.size > 0 || outbound.occupied.value
|
|
157
|
+
() => hasPendingMessage.value || runtimeBlocked.value || pendingRealResultIds.value.size > 0 || outbound.occupied.value
|
|
156
158
|
);
|
|
157
159
|
const queuedMessageContent = computed(() => outbound.slot.value?.content ?? null);
|
|
158
160
|
let requestDurableRecovery = () => {
|
|
@@ -213,8 +215,24 @@ export function useChat(options = {}) {
|
|
|
213
215
|
return resolveReasoningDisplayMessages(overlaid, reasoningCache);
|
|
214
216
|
});
|
|
215
217
|
const stopCondition = computed(
|
|
216
|
-
() => !hasPendingMessage.value && pendingStreamReconciliationIds.value.size === 0
|
|
218
|
+
() => !runtimeBlocked.value && !hasPendingMessage.value && pendingStreamReconciliationIds.value.size === 0
|
|
217
219
|
);
|
|
220
|
+
async function attachConversationStream(conversationId) {
|
|
221
|
+
if (streamConnecting || directStream.activity.value !== "idle")
|
|
222
|
+
return;
|
|
223
|
+
streamConnecting = true;
|
|
224
|
+
try {
|
|
225
|
+
await directStream.connectConversation(
|
|
226
|
+
chatApi.runtimePath(`/conversations/${conversationId}/stream`),
|
|
227
|
+
chatApi.withChatHeaders(),
|
|
228
|
+
streamingMessageId.value ?? void 0
|
|
229
|
+
);
|
|
230
|
+
} catch (err) {
|
|
231
|
+
Sentry.captureException(err);
|
|
232
|
+
} finally {
|
|
233
|
+
streamConnecting = false;
|
|
234
|
+
}
|
|
235
|
+
}
|
|
218
236
|
let pollGeneration = 0;
|
|
219
237
|
const pollMessages = async () => {
|
|
220
238
|
if (!currentConversation.value)
|
|
@@ -222,13 +240,20 @@ export function useChat(options = {}) {
|
|
|
222
240
|
if (gateHolding.value && !outboundQueueEnabled.value)
|
|
223
241
|
return;
|
|
224
242
|
const generation = pollGeneration;
|
|
243
|
+
const conversationId = currentConversation.value.id;
|
|
225
244
|
try {
|
|
245
|
+
const runtime = chatApi.conversationV2Enabled ? await $fetch(
|
|
246
|
+
chatApi.runtimePath(`/conversations/${conversationId}/runtime`),
|
|
247
|
+
chatApi.withChatHeaders()
|
|
248
|
+
) : null;
|
|
226
249
|
const response = await $fetch(
|
|
227
|
-
chatApi.path(`/conversations/${
|
|
250
|
+
chatApi.path(`/conversations/${conversationId}/messages`),
|
|
228
251
|
chatApi.withChatHeaders()
|
|
229
252
|
);
|
|
230
|
-
if (generation !== pollGeneration)
|
|
253
|
+
if (generation !== pollGeneration || currentConversation.value?.id !== conversationId)
|
|
231
254
|
return;
|
|
255
|
+
if (runtime)
|
|
256
|
+
runtimeBlocked.value = runtime.conversation.runtimeState === "blocked";
|
|
232
257
|
if (response.agentSession) {
|
|
233
258
|
agentSessionStatus.value = response.agentSession.status;
|
|
234
259
|
agentSessionExecutable.value = response.agentSession.executable;
|
|
@@ -261,6 +286,10 @@ export function useChat(options = {}) {
|
|
|
261
286
|
pendingStreamReconciliationIds.value = remainingReconciliationIds;
|
|
262
287
|
pendingRealResultIds.value = remainingRealResultIds;
|
|
263
288
|
messages.value = reconciledMessages;
|
|
289
|
+
if (runtime?.turn && runtimeBlocked.value && reconciledMessages.some((message) => message.id === runtime.turn?.id)) {
|
|
290
|
+
streamingMessageId.value = runtime.turn.id;
|
|
291
|
+
void attachConversationStream(conversationId);
|
|
292
|
+
}
|
|
264
293
|
const latestSessionId = reconciledMessages.findLast((message) => message.agentSessionId)?.agentSessionId;
|
|
265
294
|
if (latestSessionId && currentConversation.value.threadSessionId === null) {
|
|
266
295
|
currentConversation.value = {
|
|
@@ -330,7 +359,8 @@ export function useChat(options = {}) {
|
|
|
330
359
|
}
|
|
331
360
|
requestDurableRecovery = () => {
|
|
332
361
|
startPolling();
|
|
333
|
-
|
|
362
|
+
if (!chatApi.conversationV2Enabled)
|
|
363
|
+
void pollMessages();
|
|
334
364
|
};
|
|
335
365
|
const pendingModelBuckets = useState("chat-pending-model-selection", () => ({}));
|
|
336
366
|
const pendingModelSelection = computed({
|
|
@@ -371,6 +401,7 @@ export function useChat(options = {}) {
|
|
|
371
401
|
currentConversation.value = { ...conv, messages: messages.value };
|
|
372
402
|
};
|
|
373
403
|
const setConversation = (conv) => {
|
|
404
|
+
runtimeBlocked.value = false;
|
|
374
405
|
if (currentConversation.value && currentConversation.value.id !== conv.id) {
|
|
375
406
|
directStream.disconnect();
|
|
376
407
|
streamingMessageId.value = null;
|
|
@@ -386,6 +417,11 @@ export function useChat(options = {}) {
|
|
|
386
417
|
error.value = null;
|
|
387
418
|
};
|
|
388
419
|
const loadConversation = async (id) => {
|
|
420
|
+
if (chatApi.conversationV2Enabled) {
|
|
421
|
+
stopPolling();
|
|
422
|
+
directStream.disconnect();
|
|
423
|
+
}
|
|
424
|
+
runtimeBlocked.value = false;
|
|
389
425
|
loading.value = true;
|
|
390
426
|
error.value = null;
|
|
391
427
|
try {
|
|
@@ -404,6 +440,8 @@ export function useChat(options = {}) {
|
|
|
404
440
|
streamingMessageId.value = pendingAssistant.id;
|
|
405
441
|
directStream.beginMessage();
|
|
406
442
|
startPolling();
|
|
443
|
+
if (chatApi.conversationV2Enabled)
|
|
444
|
+
await pollMessages();
|
|
407
445
|
} else {
|
|
408
446
|
streamingMessageId.value = null;
|
|
409
447
|
directStream.disconnect();
|
|
@@ -423,7 +461,7 @@ export function useChat(options = {}) {
|
|
|
423
461
|
return null;
|
|
424
462
|
if (outboundQueueEnabled.value && outbound.occupied.value && !queuedSend)
|
|
425
463
|
return null;
|
|
426
|
-
if (!queuedSend && (sending.value || hasPendingMessage.value || pendingRealResultIds.value.size > 0))
|
|
464
|
+
if (!queuedSend && (sending.value || runtimeBlocked.value || hasPendingMessage.value || pendingRealResultIds.value.size > 0))
|
|
427
465
|
return null;
|
|
428
466
|
suspendPollingForSend();
|
|
429
467
|
sending.value = true;
|
|
@@ -468,6 +506,7 @@ export function useChat(options = {}) {
|
|
|
468
506
|
messages.value = [...messages.value, optimisticUserMessage, optimisticAssistantMessage];
|
|
469
507
|
const controller = new AbortController();
|
|
470
508
|
gateController = controller;
|
|
509
|
+
let v2AdmissionRequested = false;
|
|
471
510
|
try {
|
|
472
511
|
let wakeSessionId = queuedSend?.wakeSessionId;
|
|
473
512
|
let defer = false;
|
|
@@ -486,7 +525,7 @@ export function useChat(options = {}) {
|
|
|
486
525
|
if (!currentConversation.value)
|
|
487
526
|
throw new Error("Erro ao enviar mensagem");
|
|
488
527
|
const sessionReady2 = currentConversation.value.threadSessionId ? agentSessionStatus.value === "waiting_messages" && agentSessionExecutable.value : null;
|
|
489
|
-
if (outboundQueueEnabled.value && !queuedSend && (defer || sessionReady2 === false)) {
|
|
528
|
+
if (!chatApi.conversationV2Enabled && outboundQueueEnabled.value && !queuedSend && (defer || sessionReady2 === false)) {
|
|
490
529
|
outbound.enqueue({
|
|
491
530
|
content,
|
|
492
531
|
files,
|
|
@@ -530,29 +569,52 @@ export function useChat(options = {}) {
|
|
|
530
569
|
startPolling();
|
|
531
570
|
};
|
|
532
571
|
let response;
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
572
|
+
if (chatApi.conversationV2Enabled) {
|
|
573
|
+
const v2Body = {
|
|
574
|
+
messageId: optimisticUserMessage.id,
|
|
575
|
+
content,
|
|
576
|
+
files,
|
|
577
|
+
...resolvedAgentInputs !== void 0 ? { agentInputs: resolvedAgentInputs } : {},
|
|
578
|
+
clientTiming: body.clientTiming
|
|
579
|
+
};
|
|
580
|
+
const conversationId2 = currentConversation.value.id;
|
|
581
|
+
v2AdmissionRequested = true;
|
|
582
|
+
const accepted = await $fetch(
|
|
583
|
+
chatApi.runtimePath(`/conversations/${conversationId2}/messages`),
|
|
584
|
+
chatApi.withChatHeaders({ method: "POST", body: v2Body, retry: 1 })
|
|
542
585
|
);
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
586
|
+
response = accepted;
|
|
587
|
+
if (currentConversation.value?.id !== conversationId2)
|
|
588
|
+
return accepted.userMessage;
|
|
589
|
+
runtimeBlocked.value = accepted.conversation.runtimeState === "blocked";
|
|
590
|
+
acceptMessagePair(accepted);
|
|
591
|
+
if (runtimeBlocked.value)
|
|
592
|
+
void attachConversationStream(conversationId2);
|
|
593
|
+
} else {
|
|
594
|
+
try {
|
|
595
|
+
response = await directStream.connectMessage(
|
|
596
|
+
chatApi.path(`/conversations/${currentConversation.value.id}/messages/stream`),
|
|
597
|
+
chatApi.withChatHeaders({
|
|
598
|
+
method: "POST",
|
|
599
|
+
headers: { "Content-Type": "application/json" },
|
|
600
|
+
body: JSON.stringify(body)
|
|
601
|
+
}),
|
|
602
|
+
acceptMessagePair
|
|
603
|
+
);
|
|
604
|
+
} catch (streamError) {
|
|
605
|
+
const statusCode = getChatApiErrorStatus(streamError);
|
|
606
|
+
if (statusCode !== null && statusCode >= 400 && statusCode < 500)
|
|
607
|
+
throw streamError;
|
|
608
|
+
if (outboundQueueEnabled.value) {
|
|
609
|
+
startPolling();
|
|
610
|
+
return optimisticUserMessage;
|
|
611
|
+
}
|
|
612
|
+
response = await $fetch(
|
|
613
|
+
chatApi.path(`/conversations/${currentConversation.value.id}/messages`),
|
|
614
|
+
chatApi.withChatHeaders({ method: "POST", body })
|
|
615
|
+
);
|
|
616
|
+
acceptMessagePair(response);
|
|
550
617
|
}
|
|
551
|
-
response = await $fetch(
|
|
552
|
-
chatApi.path(`/conversations/${currentConversation.value.id}/messages`),
|
|
553
|
-
chatApi.withChatHeaders({ method: "POST", body })
|
|
554
|
-
);
|
|
555
|
-
acceptMessagePair(response);
|
|
556
618
|
}
|
|
557
619
|
if (files && files.length > 0) {
|
|
558
620
|
addFilesToConversation(
|
|
@@ -565,9 +627,15 @@ export function useChat(options = {}) {
|
|
|
565
627
|
return response.userMessage;
|
|
566
628
|
} catch (err) {
|
|
567
629
|
const code = getChatApiErrorCode(err);
|
|
630
|
+
const status = getChatApiErrorStatus(err);
|
|
631
|
+
if (v2AdmissionRequested && !controller.signal.aborted && (status === null || status === 408 || status === 429 || status >= 500)) {
|
|
632
|
+
error.value = "Confirma\xE7\xE3o do envio pendente. Reconectando \xE0 conversa\u2026";
|
|
633
|
+
startPolling();
|
|
634
|
+
return optimisticUserMessage;
|
|
635
|
+
}
|
|
568
636
|
const queuedAttempts = (queuedSend?.attempts ?? 0) + 1;
|
|
569
637
|
const queuedAgeMs = Date.now() - (queuedSend?.queuedAt ?? Date.now());
|
|
570
|
-
if (outboundQueueEnabled.value && (code === "turn_in_progress" || code === "sandbox_not_woken") && queuedAttempts < 3 && queuedAgeMs <= 9e4) {
|
|
638
|
+
if (!chatApi.conversationV2Enabled && outboundQueueEnabled.value && (code === "turn_in_progress" || code === "sandbox_not_woken") && queuedAttempts < 3 && queuedAgeMs <= 9e4) {
|
|
571
639
|
outbound.replace({
|
|
572
640
|
content,
|
|
573
641
|
files,
|
|
@@ -648,6 +716,7 @@ export function useChat(options = {}) {
|
|
|
648
716
|
void flushOutboundQueue();
|
|
649
717
|
});
|
|
650
718
|
const clearConversation = () => {
|
|
719
|
+
runtimeBlocked.value = false;
|
|
651
720
|
stopPolling();
|
|
652
721
|
gateController?.abort();
|
|
653
722
|
streamingMessageId.value = null;
|
|
@@ -682,11 +751,30 @@ export function useChat(options = {}) {
|
|
|
682
751
|
gateController?.abort();
|
|
683
752
|
return true;
|
|
684
753
|
}
|
|
685
|
-
if (!currentConversation.value || !hasPendingMessage.value)
|
|
754
|
+
if (!currentConversation.value || !hasPendingMessage.value || chatApi.conversationV2Enabled && sending.value)
|
|
686
755
|
return false;
|
|
687
756
|
cancelling.value = true;
|
|
688
757
|
error.value = null;
|
|
689
758
|
try {
|
|
759
|
+
if (chatApi.conversationV2Enabled) {
|
|
760
|
+
const conversationId = currentConversation.value.id;
|
|
761
|
+
const runtime = await $fetch(
|
|
762
|
+
chatApi.runtimePath(`/conversations/${conversationId}/runtime`),
|
|
763
|
+
chatApi.withChatHeaders()
|
|
764
|
+
);
|
|
765
|
+
if (currentConversation.value?.id !== conversationId)
|
|
766
|
+
return false;
|
|
767
|
+
const pending = messages.value.findLast((message) => message.role === "assistant" && message.status === "pending");
|
|
768
|
+
if (runtime.turn?.id === pending?.id && runtime.turn?.state !== "failed") {
|
|
769
|
+
const result2 = await $fetch(
|
|
770
|
+
chatApi.runtimePath(`/conversations/${conversationId}/cancel`),
|
|
771
|
+
chatApi.withChatHeaders({ method: "POST" })
|
|
772
|
+
);
|
|
773
|
+
if (currentConversation.value?.id === conversationId)
|
|
774
|
+
await pollMessages();
|
|
775
|
+
return result2.cancelled;
|
|
776
|
+
}
|
|
777
|
+
}
|
|
690
778
|
const result = await $fetch(
|
|
691
779
|
chatApi.path(`/conversations/${currentConversation.value.id}/cancel`),
|
|
692
780
|
chatApi.withChatHeaders({ method: "POST" })
|
|
@@ -43,6 +43,7 @@ export declare function useDirectStream(options?: {
|
|
|
43
43
|
streamingThinking: any;
|
|
44
44
|
activeRunId: any;
|
|
45
45
|
connectMessage: (url: string, init: RequestInit, onAccepted: (response: SendMessageResponse) => void) => Promise<SendMessageResponse>;
|
|
46
|
+
connectConversation: (url: string, init: RequestInit, expectedAssistantMessageId?: string) => Promise<void>;
|
|
46
47
|
beginMessage: () => void;
|
|
47
48
|
disconnect: (reset?: boolean) => void;
|
|
48
49
|
};
|
|
@@ -137,7 +137,7 @@ export function useDirectStream(options = {}) {
|
|
|
137
137
|
if (reset)
|
|
138
138
|
resetAccumulator();
|
|
139
139
|
}
|
|
140
|
-
async function
|
|
140
|
+
async function connectStream(url, init, onAccepted, expectedAssistantMessageId) {
|
|
141
141
|
if (import.meta.server)
|
|
142
142
|
throw new Error("Message streaming is unavailable during server rendering");
|
|
143
143
|
abortController?.abort();
|
|
@@ -170,6 +170,8 @@ export function useDirectStream(options = {}) {
|
|
|
170
170
|
abortController = null;
|
|
171
171
|
throw new Error("Message stream response has no body");
|
|
172
172
|
}
|
|
173
|
+
if (controller.signal.aborted)
|
|
174
|
+
throw new DOMException("Aborted", "AbortError");
|
|
173
175
|
activity.value = "connected";
|
|
174
176
|
let resolveAccepted;
|
|
175
177
|
let rejectAccepted;
|
|
@@ -177,7 +179,9 @@ export function useDirectStream(options = {}) {
|
|
|
177
179
|
resolveAccepted = resolve;
|
|
178
180
|
rejectAccepted = reject;
|
|
179
181
|
});
|
|
180
|
-
let accepted =
|
|
182
|
+
let accepted = !onAccepted;
|
|
183
|
+
if (accepted)
|
|
184
|
+
resolveAccepted();
|
|
181
185
|
let optimisticResultReported = false;
|
|
182
186
|
let terminalEventObserved = false;
|
|
183
187
|
let terminalReported = false;
|
|
@@ -244,6 +248,8 @@ export function useDirectStream(options = {}) {
|
|
|
244
248
|
if (frame.data === "[DONE]")
|
|
245
249
|
continue;
|
|
246
250
|
if (frame.event === "message-accepted") {
|
|
251
|
+
if (!onAccepted)
|
|
252
|
+
continue;
|
|
247
253
|
try {
|
|
248
254
|
const messagePair = reviveMessagePair(JSON.parse(frame.data));
|
|
249
255
|
accepted = true;
|
|
@@ -262,6 +268,11 @@ export function useDirectStream(options = {}) {
|
|
|
262
268
|
}
|
|
263
269
|
if (!isRecord(event) || typeof event.kind !== "string")
|
|
264
270
|
continue;
|
|
271
|
+
if (event.kind === "conversation-state" && expectedAssistantMessageId && event.assistantMessageId !== expectedAssistantMessageId) {
|
|
272
|
+
controller.abort();
|
|
273
|
+
requestRecovery();
|
|
274
|
+
break;
|
|
275
|
+
}
|
|
265
276
|
activity.value = "active";
|
|
266
277
|
if (event.kind === "result") {
|
|
267
278
|
settleResult(event.status);
|
|
@@ -301,8 +312,11 @@ export function useDirectStream(options = {}) {
|
|
|
301
312
|
if (!accepted)
|
|
302
313
|
rejectAccepted(error);
|
|
303
314
|
} finally {
|
|
304
|
-
if (abortController === controller)
|
|
315
|
+
if (abortController === controller) {
|
|
305
316
|
abortController = null;
|
|
317
|
+
if (!onAccepted)
|
|
318
|
+
activity.value = "idle";
|
|
319
|
+
}
|
|
306
320
|
if (accepted && !terminalEventObserved && !controller.signal.aborted)
|
|
307
321
|
requestRecovery();
|
|
308
322
|
}
|
|
@@ -315,7 +329,8 @@ export function useDirectStream(options = {}) {
|
|
|
315
329
|
streamingText: readonly(streamingText),
|
|
316
330
|
streamingThinking: readonly(streamingThinking),
|
|
317
331
|
activeRunId: readonly(activeRunId),
|
|
318
|
-
connectMessage,
|
|
332
|
+
connectMessage: (url, init, onAccepted) => connectStream(url, init, onAccepted),
|
|
333
|
+
connectConversation: (url, init, expectedAssistantMessageId) => connectStream(url, { ...init, method: "GET" }, void 0, expectedAssistantMessageId),
|
|
319
334
|
beginMessage,
|
|
320
335
|
disconnect
|
|
321
336
|
};
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import type { H3Event } from 'h3';
|
|
2
|
+
export type ChatApiVersion = 'v1' | 'v2';
|
|
3
|
+
export declare function resolveChatBasePath(basePath: string, apiVersion: ChatApiVersion): string;
|
|
2
4
|
export declare function mapVaultProxyPath(path: string): string;
|
|
3
5
|
export declare function mapWorkspaceProxyPath(path: string): string;
|
|
4
6
|
export declare function prefixProxyPath(prefix: string, path: string): string;
|
|
5
|
-
export declare function proxyChatApiRequest(event: H3Event, targetPath: string
|
|
6
|
-
|
|
7
|
+
export declare function proxyChatApiRequest(event: H3Event, targetPath: string, options?: {
|
|
8
|
+
apiVersion?: ChatApiVersion;
|
|
9
|
+
}): Promise<any>;
|
|
10
|
+
export declare function defineChatApiProxyHandler(resolveTargetPath: (path: string) => string, options?: {
|
|
11
|
+
apiVersion?: ChatApiVersion;
|
|
12
|
+
}): import("h3").EventHandler<import("h3").EventHandlerRequest, Promise<any>>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGENT_API_V5_CONFIG_KEY, PREPARED_AGENT_RUNTIME_CONFIG_KEY, SECRETLESS_EXECUTION_CONFIG_KEY } from "../../types/schemas/chat/chat-config.js";
|
|
1
|
+
import { AGENT_API_V5_CONFIG_KEY, CONVERSATION_V2_CONFIG_KEY, PREPARED_AGENT_RUNTIME_CONFIG_KEY, SECRETLESS_EXECUTION_CONFIG_KEY } from "../../types/schemas/chat/chat-config.js";
|
|
2
2
|
import { createError, defineEventHandler, getHeader, getRequestURL, getRouterParam, proxyRequest } from "h3";
|
|
3
3
|
import { useRuntimeConfig } from "nitropack/runtime";
|
|
4
4
|
import { resolveAuthToken } from "./auth-token.js";
|
|
@@ -43,10 +43,20 @@ function resolveChatApiUrl(event) {
|
|
|
43
43
|
}
|
|
44
44
|
return chatApiUrl;
|
|
45
45
|
}
|
|
46
|
-
function
|
|
46
|
+
export function resolveChatBasePath(basePath, apiVersion) {
|
|
47
|
+
const versionSuffix = `${apiVersion}/chat`;
|
|
48
|
+
if (basePath.endsWith("v1/chat")) {
|
|
49
|
+
return apiVersion === "v1" ? basePath : joinProxyPath(basePath.slice(0, -"v1/chat".length), versionSuffix);
|
|
50
|
+
}
|
|
51
|
+
if (basePath.endsWith("v1")) {
|
|
52
|
+
return apiVersion === "v1" ? joinProxyPath(basePath, "chat") : joinProxyPath(basePath.slice(0, -"v1".length), versionSuffix);
|
|
53
|
+
}
|
|
54
|
+
return joinProxyPath(basePath, versionSuffix);
|
|
55
|
+
}
|
|
56
|
+
function buildTargetUrl(event, targetPath, apiVersion = "v1") {
|
|
47
57
|
const base = new URL(resolveChatApiUrl(event));
|
|
48
58
|
const basePath = normalizeProxyPath(base.pathname);
|
|
49
|
-
const chatBasePath =
|
|
59
|
+
const chatBasePath = resolveChatBasePath(basePath, apiVersion);
|
|
50
60
|
base.pathname = `/${joinProxyPath(chatBasePath, targetPath)}`;
|
|
51
61
|
base.search = getRequestURL(event).search;
|
|
52
62
|
return base.toString();
|
|
@@ -60,7 +70,10 @@ function buildProxyHeaders(event) {
|
|
|
60
70
|
});
|
|
61
71
|
}
|
|
62
72
|
const config = useRuntimeConfig(event);
|
|
63
|
-
const chatConfig = {
|
|
73
|
+
const chatConfig = {
|
|
74
|
+
[PREPARED_AGENT_RUNTIME_CONFIG_KEY]: true,
|
|
75
|
+
[CONVERSATION_V2_CONFIG_KEY]: true
|
|
76
|
+
};
|
|
64
77
|
if (config.chatNuxt?.secretlessExecution) {
|
|
65
78
|
chatConfig[SECRETLESS_EXECUTION_CONFIG_KEY] = true;
|
|
66
79
|
}
|
|
@@ -110,8 +123,8 @@ export function mapWorkspaceProxyPath(path) {
|
|
|
110
123
|
export function prefixProxyPath(prefix, path) {
|
|
111
124
|
return joinProxyPath(prefix, path);
|
|
112
125
|
}
|
|
113
|
-
export async function proxyChatApiRequest(event, targetPath) {
|
|
114
|
-
return proxyRequest(event, buildTargetUrl(event, targetPath), {
|
|
126
|
+
export async function proxyChatApiRequest(event, targetPath, options = {}) {
|
|
127
|
+
return proxyRequest(event, buildTargetUrl(event, targetPath, options.apiVersion ?? "v1"), {
|
|
115
128
|
fetchOptions: {
|
|
116
129
|
redirect: "manual"
|
|
117
130
|
},
|
|
@@ -119,9 +132,9 @@ export async function proxyChatApiRequest(event, targetPath) {
|
|
|
119
132
|
streamRequest: true
|
|
120
133
|
});
|
|
121
134
|
}
|
|
122
|
-
export function defineChatApiProxyHandler(resolveTargetPath) {
|
|
135
|
+
export function defineChatApiProxyHandler(resolveTargetPath, options = {}) {
|
|
123
136
|
return defineEventHandler((event) => {
|
|
124
137
|
const path = getRouterParam(event, "path") || "";
|
|
125
|
-
return proxyChatApiRequest(event, resolveTargetPath(path));
|
|
138
|
+
return proxyChatApiRequest(event, resolveTargetPath(path), options);
|
|
126
139
|
});
|
|
127
140
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export declare function useChatApi(): {
|
|
2
2
|
path: (routePath: string) => string;
|
|
3
|
+
runtimePath: (routePath: string) => string;
|
|
4
|
+
conversationV2Enabled: boolean;
|
|
3
5
|
withChatHeaders: <const T extends Record<string, any>>(options?: T) => T & {
|
|
4
6
|
headers?: Record<string, string>;
|
|
5
7
|
};
|
|
@@ -5,7 +5,7 @@ export type { ChatActionPayload } from '../messages/composables/chat-action.js';
|
|
|
5
5
|
export type { MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, MessageFeedbackSubmitHandler, MessageFeedbackSubmitResult, } from '../messages/composables/chat-feedback.js';
|
|
6
6
|
export { ChatMessageStatus } from '../messages/composables/chat-message-terminal.js';
|
|
7
7
|
export type { ChatMessageTerminalPayload } from '../messages/composables/chat-message-terminal.js';
|
|
8
|
-
export type { ConversationEvent } from './schemas/chat/conversations.js';
|
|
8
|
+
export type { ConversationEvent, Message } from './schemas/chat/conversations.js';
|
|
9
9
|
export type { MessageOverviewResponse } from './schemas/chat/messages.js';
|
|
10
10
|
export type { ConversationCreatorFilter } from './schemas/chat/primitives.js';
|
|
11
11
|
export type { TelaAgentExecutionInput } from './schemas/integrations/tela-agent-api.js';
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare const PREPARED_AGENT_RUNTIME_CONFIG_KEY = "prepared-agent-runtime";
|
|
2
2
|
export declare const SECRETLESS_EXECUTION_CONFIG_KEY = "secretless-execution";
|
|
3
3
|
export declare const AGENT_API_V5_CONFIG_KEY = "agent-api-v5";
|
|
4
|
+
export declare const CONVERSATION_V2_CONFIG_KEY = "conversation-v2";
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const conversationRuntimeStateSchema: z.ZodEnum<{
|
|
3
|
+
waiting_messages: "waiting_messages";
|
|
4
|
+
blocked: "blocked";
|
|
5
|
+
}>;
|
|
6
|
+
export type ConversationRuntimeState = z.infer<typeof conversationRuntimeStateSchema>;
|
|
7
|
+
export declare const turnRuntimeStateNameSchema: z.ZodEnum<{
|
|
8
|
+
running: "running";
|
|
9
|
+
completed: "completed";
|
|
10
|
+
failed: "failed";
|
|
11
|
+
cancelled: "cancelled";
|
|
12
|
+
accepted: "accepted";
|
|
13
|
+
checking_session: "checking_session";
|
|
14
|
+
waiting_for_wake: "waiting_for_wake";
|
|
15
|
+
dispatching: "dispatching";
|
|
16
|
+
streaming: "streaming";
|
|
17
|
+
}>;
|
|
18
|
+
export type TurnRuntimeStateName = z.infer<typeof turnRuntimeStateNameSchema>;
|
|
19
|
+
export declare const conversationWakeStateSchema: z.ZodEnum<{
|
|
20
|
+
failed: "failed";
|
|
21
|
+
waking: "waking";
|
|
22
|
+
parked: "parked";
|
|
23
|
+
ready: "ready";
|
|
24
|
+
stale: "stale";
|
|
25
|
+
checking: "checking";
|
|
26
|
+
}>;
|
|
27
|
+
export type ConversationWakeState = z.infer<typeof conversationWakeStateSchema>;
|
|
28
|
+
export declare const wakeConversationResponseSchema: z.ZodObject<{
|
|
29
|
+
state: z.ZodEnum<{
|
|
30
|
+
failed: "failed";
|
|
31
|
+
waking: "waking";
|
|
32
|
+
parked: "parked";
|
|
33
|
+
ready: "ready";
|
|
34
|
+
stale: "stale";
|
|
35
|
+
checking: "checking";
|
|
36
|
+
}>;
|
|
37
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
38
|
+
error: z.ZodNullable<z.ZodString>;
|
|
39
|
+
}, z.core.$strip>;
|
|
40
|
+
export type WakeConversationResponse = z.infer<typeof wakeConversationResponseSchema>;
|
|
41
|
+
export declare const turnSnapshotSchema: z.ZodObject<{
|
|
42
|
+
id: z.ZodString;
|
|
43
|
+
state: z.ZodEnum<{
|
|
44
|
+
running: "running";
|
|
45
|
+
completed: "completed";
|
|
46
|
+
failed: "failed";
|
|
47
|
+
cancelled: "cancelled";
|
|
48
|
+
accepted: "accepted";
|
|
49
|
+
checking_session: "checking_session";
|
|
50
|
+
waiting_for_wake: "waiting_for_wake";
|
|
51
|
+
dispatching: "dispatching";
|
|
52
|
+
streaming: "streaming";
|
|
53
|
+
}>;
|
|
54
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
55
|
+
error: z.ZodNullable<z.ZodString>;
|
|
56
|
+
}, z.core.$strip>;
|
|
57
|
+
export type TurnSnapshot = z.infer<typeof turnSnapshotSchema>;
|
|
58
|
+
export declare const sendMessageV2BodySchema: z.ZodObject<{
|
|
59
|
+
messageId: z.ZodString;
|
|
60
|
+
content: z.ZodString;
|
|
61
|
+
files: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
62
|
+
url: z.ZodString;
|
|
63
|
+
name: z.ZodString;
|
|
64
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
65
|
+
vaultReference: z.ZodOptional<z.ZodString>;
|
|
66
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
67
|
+
}, z.core.$strip>>>;
|
|
68
|
+
agentInputs: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
69
|
+
type: z.ZodLiteral<"file">;
|
|
70
|
+
name: z.ZodString;
|
|
71
|
+
vaultRef: z.ZodString;
|
|
72
|
+
filename: z.ZodString;
|
|
73
|
+
metadata: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
75
|
+
type: z.ZodLiteral<"text">;
|
|
76
|
+
name: z.ZodString;
|
|
77
|
+
content: z.ZodString;
|
|
78
|
+
}, z.core.$strip>], "type">>>;
|
|
79
|
+
clientTiming: z.ZodOptional<z.ZodObject<{
|
|
80
|
+
sinceSendMs: z.ZodNumber;
|
|
81
|
+
standInOutputAtMs: z.ZodOptional<z.ZodNumber>;
|
|
82
|
+
}, z.core.$strict>>;
|
|
83
|
+
}, z.core.$strict>;
|
|
84
|
+
export type SendMessageV2Body = z.infer<typeof sendMessageV2BodySchema>;
|
|
85
|
+
export declare const sendMessageV2ResponseSchema: z.ZodObject<{
|
|
86
|
+
userMessage: z.ZodObject<{
|
|
87
|
+
id: z.ZodString;
|
|
88
|
+
conversationId: z.ZodString;
|
|
89
|
+
role: z.ZodEnum<{
|
|
90
|
+
user: "user";
|
|
91
|
+
assistant: "assistant";
|
|
92
|
+
}>;
|
|
93
|
+
content: z.ZodString;
|
|
94
|
+
status: z.ZodNullable<z.ZodEnum<{
|
|
95
|
+
pending: "pending";
|
|
96
|
+
completed: "completed";
|
|
97
|
+
failed: "failed";
|
|
98
|
+
}>>;
|
|
99
|
+
failReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
100
|
+
reasoningData: z.ZodUnknown;
|
|
101
|
+
files: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
102
|
+
url: z.ZodString;
|
|
103
|
+
vaultReference: z.ZodOptional<z.ZodString>;
|
|
104
|
+
name: z.ZodString;
|
|
105
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
106
|
+
source: z.ZodEnum<{
|
|
107
|
+
user: "user";
|
|
108
|
+
assistant: "assistant";
|
|
109
|
+
}>;
|
|
110
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
111
|
+
}, z.core.$strip>>>;
|
|
112
|
+
externalUuid: z.ZodNullable<z.ZodString>;
|
|
113
|
+
ttft: z.ZodNullable<z.ZodString>;
|
|
114
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
115
|
+
createdAt: z.ZodDate;
|
|
116
|
+
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
117
|
+
}, z.core.$strip>;
|
|
118
|
+
assistantMessage: z.ZodObject<{
|
|
119
|
+
id: z.ZodString;
|
|
120
|
+
conversationId: z.ZodString;
|
|
121
|
+
role: z.ZodEnum<{
|
|
122
|
+
user: "user";
|
|
123
|
+
assistant: "assistant";
|
|
124
|
+
}>;
|
|
125
|
+
content: z.ZodString;
|
|
126
|
+
status: z.ZodNullable<z.ZodEnum<{
|
|
127
|
+
pending: "pending";
|
|
128
|
+
completed: "completed";
|
|
129
|
+
failed: "failed";
|
|
130
|
+
}>>;
|
|
131
|
+
failReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
132
|
+
reasoningData: z.ZodUnknown;
|
|
133
|
+
files: z.ZodNullable<z.ZodArray<z.ZodObject<{
|
|
134
|
+
url: z.ZodString;
|
|
135
|
+
vaultReference: z.ZodOptional<z.ZodString>;
|
|
136
|
+
name: z.ZodString;
|
|
137
|
+
mimeType: z.ZodOptional<z.ZodString>;
|
|
138
|
+
source: z.ZodEnum<{
|
|
139
|
+
user: "user";
|
|
140
|
+
assistant: "assistant";
|
|
141
|
+
}>;
|
|
142
|
+
size: z.ZodOptional<z.ZodNumber>;
|
|
143
|
+
}, z.core.$strip>>>;
|
|
144
|
+
externalUuid: z.ZodNullable<z.ZodString>;
|
|
145
|
+
ttft: z.ZodNullable<z.ZodString>;
|
|
146
|
+
createdBy: z.ZodNullable<z.ZodString>;
|
|
147
|
+
createdAt: z.ZodDate;
|
|
148
|
+
updatedAt: z.ZodNullable<z.ZodDate>;
|
|
149
|
+
}, z.core.$strip>;
|
|
150
|
+
turn: z.ZodNullable<z.ZodObject<{
|
|
151
|
+
id: z.ZodString;
|
|
152
|
+
state: z.ZodEnum<{
|
|
153
|
+
running: "running";
|
|
154
|
+
completed: "completed";
|
|
155
|
+
failed: "failed";
|
|
156
|
+
cancelled: "cancelled";
|
|
157
|
+
accepted: "accepted";
|
|
158
|
+
checking_session: "checking_session";
|
|
159
|
+
waiting_for_wake: "waiting_for_wake";
|
|
160
|
+
dispatching: "dispatching";
|
|
161
|
+
streaming: "streaming";
|
|
162
|
+
}>;
|
|
163
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
164
|
+
error: z.ZodNullable<z.ZodString>;
|
|
165
|
+
}, z.core.$strip>>;
|
|
166
|
+
conversation: z.ZodObject<{
|
|
167
|
+
runtimeState: z.ZodEnum<{
|
|
168
|
+
waiting_messages: "waiting_messages";
|
|
169
|
+
blocked: "blocked";
|
|
170
|
+
}>;
|
|
171
|
+
}, z.core.$strip>;
|
|
172
|
+
}, z.core.$strip>;
|
|
173
|
+
export type SendMessageV2Response = z.infer<typeof sendMessageV2ResponseSchema>;
|
|
174
|
+
export declare const conversationRuntimeV2ResponseSchema: z.ZodObject<{
|
|
175
|
+
conversation: z.ZodObject<{
|
|
176
|
+
runtimeState: z.ZodEnum<{
|
|
177
|
+
waiting_messages: "waiting_messages";
|
|
178
|
+
blocked: "blocked";
|
|
179
|
+
}>;
|
|
180
|
+
}, z.core.$strip>;
|
|
181
|
+
turn: z.ZodNullable<z.ZodObject<{
|
|
182
|
+
id: z.ZodString;
|
|
183
|
+
state: z.ZodEnum<{
|
|
184
|
+
running: "running";
|
|
185
|
+
completed: "completed";
|
|
186
|
+
failed: "failed";
|
|
187
|
+
cancelled: "cancelled";
|
|
188
|
+
accepted: "accepted";
|
|
189
|
+
checking_session: "checking_session";
|
|
190
|
+
waiting_for_wake: "waiting_for_wake";
|
|
191
|
+
dispatching: "dispatching";
|
|
192
|
+
streaming: "streaming";
|
|
193
|
+
}>;
|
|
194
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
195
|
+
error: z.ZodNullable<z.ZodString>;
|
|
196
|
+
}, z.core.$strip>>;
|
|
197
|
+
}, z.core.$strip>;
|
|
198
|
+
export type ConversationRuntimeV2Response = z.infer<typeof conversationRuntimeV2ResponseSchema>;
|
|
199
|
+
export declare const cancelConversationV2ResponseSchema: z.ZodObject<{
|
|
200
|
+
success: z.ZodLiteral<true>;
|
|
201
|
+
cancelled: z.ZodBoolean;
|
|
202
|
+
turn: z.ZodNullable<z.ZodObject<{
|
|
203
|
+
id: z.ZodString;
|
|
204
|
+
state: z.ZodEnum<{
|
|
205
|
+
running: "running";
|
|
206
|
+
completed: "completed";
|
|
207
|
+
failed: "failed";
|
|
208
|
+
cancelled: "cancelled";
|
|
209
|
+
accepted: "accepted";
|
|
210
|
+
checking_session: "checking_session";
|
|
211
|
+
waiting_for_wake: "waiting_for_wake";
|
|
212
|
+
dispatching: "dispatching";
|
|
213
|
+
streaming: "streaming";
|
|
214
|
+
}>;
|
|
215
|
+
sessionId: z.ZodNullable<z.ZodString>;
|
|
216
|
+
error: z.ZodNullable<z.ZodString>;
|
|
217
|
+
}, z.core.$strip>>;
|
|
218
|
+
}, z.core.$strip>;
|
|
219
|
+
export type CancelConversationV2Response = z.infer<typeof cancelConversationV2ResponseSchema>;
|
|
220
|
+
export declare const conversationRuntimeWebhookPayloadSchema: z.ZodObject<{
|
|
221
|
+
eventType: z.ZodEnum<{
|
|
222
|
+
"session.started": "session.started";
|
|
223
|
+
"session.completed": "session.completed";
|
|
224
|
+
"session.failed": "session.failed";
|
|
225
|
+
"session.cancelled": "session.cancelled";
|
|
226
|
+
"session.waiting_messages": "session.waiting_messages";
|
|
227
|
+
}>;
|
|
228
|
+
sessionId: z.ZodString;
|
|
229
|
+
status: z.ZodOptional<z.ZodString>;
|
|
230
|
+
error: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
231
|
+
failReason: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
232
|
+
result: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
|
|
233
|
+
deliveryId: z.ZodOptional<z.ZodString>;
|
|
234
|
+
}, z.core.$catchall<z.ZodUnknown>>;
|
|
235
|
+
export type ConversationRuntimeWebhookPayload = z.infer<typeof conversationRuntimeWebhookPayloadSchema>;
|
|
236
|
+
export declare const conversationRuntimeWebhookResponseSchema: z.ZodObject<{
|
|
237
|
+
handled: z.ZodBoolean;
|
|
238
|
+
}, z.core.$strip>;
|
|
239
|
+
export type ConversationRuntimeWebhookResponse = z.infer<typeof conversationRuntimeWebhookResponseSchema>;
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { telaAgentExecutionInputSchema } from '../integrations/tela-agent-api';
|
|
3
|
+
import { messageSchema } from './conversations';
|
|
4
|
+
import { fileUploadInputSchema } from './files';
|
|
5
|
+
import { sendMessageClientTimingSchema } from './messages';
|
|
6
|
+
export const conversationRuntimeStateSchema = z.enum(['blocked', 'waiting_messages']);
|
|
7
|
+
export const turnRuntimeStateNameSchema = z.enum([
|
|
8
|
+
'accepted',
|
|
9
|
+
'checking_session',
|
|
10
|
+
'waiting_for_wake',
|
|
11
|
+
'dispatching',
|
|
12
|
+
'running',
|
|
13
|
+
'streaming',
|
|
14
|
+
'completed',
|
|
15
|
+
'failed',
|
|
16
|
+
'cancelled',
|
|
17
|
+
]);
|
|
18
|
+
export const conversationWakeStateSchema = z.enum(['stale', 'checking', 'waking', 'ready', 'parked', 'failed']);
|
|
19
|
+
export const wakeConversationResponseSchema = z.object({
|
|
20
|
+
state: conversationWakeStateSchema,
|
|
21
|
+
sessionId: z.string().nullable(),
|
|
22
|
+
error: z.string().nullable(),
|
|
23
|
+
});
|
|
24
|
+
export const turnSnapshotSchema = z.object({
|
|
25
|
+
id: z.string(),
|
|
26
|
+
state: turnRuntimeStateNameSchema,
|
|
27
|
+
sessionId: z.string().nullable(),
|
|
28
|
+
error: z.string().nullable(),
|
|
29
|
+
});
|
|
30
|
+
export const sendMessageV2BodySchema = z.strictObject({
|
|
31
|
+
messageId: z.string().uuid(),
|
|
32
|
+
content: z.string(),
|
|
33
|
+
files: z.array(fileUploadInputSchema).optional(),
|
|
34
|
+
agentInputs: z.array(telaAgentExecutionInputSchema).optional(),
|
|
35
|
+
clientTiming: sendMessageClientTimingSchema.optional(),
|
|
36
|
+
});
|
|
37
|
+
export const sendMessageV2ResponseSchema = z.object({
|
|
38
|
+
userMessage: messageSchema,
|
|
39
|
+
assistantMessage: messageSchema,
|
|
40
|
+
turn: turnSnapshotSchema.nullable(),
|
|
41
|
+
conversation: z.object({ runtimeState: conversationRuntimeStateSchema }),
|
|
42
|
+
});
|
|
43
|
+
export const conversationRuntimeV2ResponseSchema = z.object({
|
|
44
|
+
conversation: z.object({ runtimeState: conversationRuntimeStateSchema }),
|
|
45
|
+
turn: turnSnapshotSchema.nullable(),
|
|
46
|
+
});
|
|
47
|
+
export const cancelConversationV2ResponseSchema = z.object({
|
|
48
|
+
success: z.literal(true),
|
|
49
|
+
cancelled: z.boolean(),
|
|
50
|
+
turn: turnSnapshotSchema.nullable(),
|
|
51
|
+
});
|
|
52
|
+
export const conversationRuntimeWebhookPayloadSchema = z.object({
|
|
53
|
+
eventType: z.enum([
|
|
54
|
+
'session.started',
|
|
55
|
+
'session.completed',
|
|
56
|
+
'session.failed',
|
|
57
|
+
'session.cancelled',
|
|
58
|
+
'session.waiting_messages',
|
|
59
|
+
]),
|
|
60
|
+
sessionId: z.string().min(1),
|
|
61
|
+
status: z.string().optional(),
|
|
62
|
+
error: z.string().nullable().optional(),
|
|
63
|
+
failReason: z.string().nullable().optional(),
|
|
64
|
+
result: z.union([z.string(), z.record(z.string(), z.unknown())]).nullable().optional(),
|
|
65
|
+
deliveryId: z.string().optional(),
|
|
66
|
+
}).catchall(z.unknown());
|
|
67
|
+
export const conversationRuntimeWebhookResponseSchema = z.object({
|
|
68
|
+
handled: z.boolean(),
|
|
69
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meistrari/chat-nuxt",
|
|
3
|
-
"version": "3.17.0-rc.
|
|
3
|
+
"version": "3.17.0-rc.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -32,6 +32,8 @@
|
|
|
32
32
|
"test:types": "pnpm build && tsc -p tsconfig.type-tests.json --noEmit",
|
|
33
33
|
"smoke:pack": "./scripts/smoke-pack-consumer.sh",
|
|
34
34
|
"smoke:browser": "./scripts/smoke-pack-consumer.sh --browser",
|
|
35
|
+
"smoke:browser:v1": "./scripts/smoke-pack-consumer.sh --browser-v1",
|
|
36
|
+
"smoke:browser:v2": "./scripts/smoke-pack-consumer.sh --browser-v2",
|
|
35
37
|
"lint": "eslint .",
|
|
36
38
|
"lint:fix": "eslint . --fix",
|
|
37
39
|
"lint:attrs": "! grep -rn '[a-z0-9-]![[:space:]>@\"'\"'\"']' --include='*.vue' src/runtime/ 2>/dev/null",
|