@meistrari/chat-nuxt 4.11.0-rc.4 → 4.11.0-rc.6
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.d.mts +2 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +1 -0
- package/dist/runtime/conversations/composables/conversations.d.ts +3 -1
- package/dist/runtime/conversations/composables/conversations.js +41 -3
- package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +10 -10
- package/dist/runtime/embed/components/chat-embed-inner.vue +119 -37
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +10 -10
- package/dist/runtime/embed/components/chat-fork-preparation.d.vue.ts +14 -0
- package/dist/runtime/embed/components/chat-fork-preparation.vue +48 -0
- package/dist/runtime/embed/components/chat-fork-preparation.vue.d.ts +14 -0
- package/dist/runtime/messages/components/chat-conversation-event.vue +2 -0
- package/dist/runtime/messages/components/chat-message-bubble.d.vue.ts +1 -0
- package/dist/runtime/messages/components/chat-message-bubble.vue +26 -19
- package/dist/runtime/messages/components/chat-message-bubble.vue.d.ts +1 -0
- package/dist/runtime/messages/components/chat-message-list.d.vue.ts +1 -0
- package/dist/runtime/messages/components/chat-message-list.vue +3 -1
- package/dist/runtime/messages/components/chat-message-list.vue.d.ts +1 -0
- package/dist/runtime/messages/conversation-timeline.d.ts +1 -0
- package/dist/runtime/messages/conversation-timeline.js +12 -3
- package/dist/runtime/server/utils/chat-api-proxy.js +4 -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 +22 -0
- package/dist/runtime/types/schemas/chat/conversation-runtime.js +3 -3
- package/dist/runtime/types/schemas/chat/conversations.d.ts +34 -0
- package/dist/runtime/types/schemas/chat/conversations.js +8 -0
- package/package.json +1 -1
package/dist/module.d.mts
CHANGED
|
@@ -41,6 +41,8 @@ interface ChatNuxtModuleOptions {
|
|
|
41
41
|
* to `false`; also settable via `NUXT_CHAT_NUXT_AGENT_API_V5`.
|
|
42
42
|
*/
|
|
43
43
|
agentApiV5?: boolean;
|
|
44
|
+
/** Opt this host into whole-session lightweight v4 forks via x-chat-config. */
|
|
45
|
+
lightweightSessionFork?: boolean;
|
|
44
46
|
/** Opt in to the 24-hour server-side pre-wake lookup cache. Defaults to false. */
|
|
45
47
|
preWakeCache?: boolean;
|
|
46
48
|
/**
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -469,6 +469,7 @@ const module$1 = defineNuxtModule({
|
|
|
469
469
|
// Explicit boolean default keeps the key in runtime config so the
|
|
470
470
|
// NUXT_CHAT_NUXT_SECRETLESS_EXECUTION env override can apply.
|
|
471
471
|
secretlessExecution: options.secretlessExecution ?? existingChatNuxtRuntimeConfig?.secretlessExecution ?? false,
|
|
472
|
+
lightweightSessionFork: options.lightweightSessionFork ?? existingChatNuxtRuntimeConfig?.lightweightSessionFork ?? false,
|
|
472
473
|
preWakeCache: options.preWakeCache ?? existingChatNuxtRuntimeConfig?.preWakeCache ?? false,
|
|
473
474
|
agentApiV5: options.agentApiV5 ?? existingChatNuxtRuntimeConfig?.agentApiV5 ?? false,
|
|
474
475
|
// Explicit boolean default keeps the key in runtime config so the
|
|
@@ -17,7 +17,9 @@ export declare function useConversations(): {
|
|
|
17
17
|
updateConversationReasoningEffort: (id: string, reasoningEffort: ChatReasoningEffort | null) => Promise<boolean>;
|
|
18
18
|
updateConversationExecutionProfile: (id: string, profile: ChatExecutionProfile) => Promise<boolean>;
|
|
19
19
|
moveConversationToGroup: (id: string, groupId: string | null) => Promise<boolean>;
|
|
20
|
-
duplicateConversation: (id: string
|
|
20
|
+
duplicateConversation: (id: string, options?: {
|
|
21
|
+
newAttempt?: boolean;
|
|
22
|
+
}) => Promise<ConversationWithMessages | null>;
|
|
21
23
|
forkConversation: (id: string, messageId: string) => Promise<ConversationWithMessages | null>;
|
|
22
24
|
conversationCreatorFilter: any;
|
|
23
25
|
conversationCreatorFilterCounts: any;
|
|
@@ -47,6 +47,31 @@ function removeBucketValue(bucket, key) {
|
|
|
47
47
|
function hasBucketValue(bucket, key) {
|
|
48
48
|
return Object.prototype.hasOwnProperty.call(bucket.value, key);
|
|
49
49
|
}
|
|
50
|
+
const duplicateKeys = /* @__PURE__ */ new Map();
|
|
51
|
+
const duplicatesInFlight = /* @__PURE__ */ new Set();
|
|
52
|
+
function reserveDuplicateKey(requestKey, newAttempt) {
|
|
53
|
+
let key = newAttempt ? void 0 : duplicateKeys.get(requestKey);
|
|
54
|
+
if (!key && !newAttempt) {
|
|
55
|
+
try {
|
|
56
|
+
key = sessionStorage.getItem(requestKey) ?? void 0;
|
|
57
|
+
} catch {
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
key ??= crypto.randomUUID();
|
|
61
|
+
duplicateKeys.set(requestKey, key);
|
|
62
|
+
try {
|
|
63
|
+
sessionStorage.setItem(requestKey, key);
|
|
64
|
+
} catch {
|
|
65
|
+
}
|
|
66
|
+
return key;
|
|
67
|
+
}
|
|
68
|
+
function releaseDuplicateKey(requestKey) {
|
|
69
|
+
duplicateKeys.delete(requestKey);
|
|
70
|
+
try {
|
|
71
|
+
sessionStorage.removeItem(requestKey);
|
|
72
|
+
} catch {
|
|
73
|
+
}
|
|
74
|
+
}
|
|
50
75
|
function conversationBucketKeyForRuntime(runtimeScope, filter) {
|
|
51
76
|
return `${runtimeScope}:creator:${filter}`;
|
|
52
77
|
}
|
|
@@ -524,17 +549,24 @@ export function useConversations() {
|
|
|
524
549
|
return null;
|
|
525
550
|
}
|
|
526
551
|
};
|
|
527
|
-
const duplicateConversation = async (id) => {
|
|
552
|
+
const duplicateConversation = async (id, options = {}) => {
|
|
528
553
|
error.value = null;
|
|
529
554
|
const statusToast = useStatusToast();
|
|
530
555
|
const requestRuntimeScope = runtimeScope.value;
|
|
556
|
+
const requestKey = `chat-duplicate:${requestRuntimeScope}:${id}`;
|
|
557
|
+
if (duplicatesInFlight.has(requestKey))
|
|
558
|
+
return null;
|
|
559
|
+
duplicatesInFlight.add(requestKey);
|
|
560
|
+
const idempotencyKey = reserveDuplicateKey(requestKey, options.newAttempt === true);
|
|
531
561
|
try {
|
|
532
562
|
const duplicated = await $fetch(
|
|
533
563
|
chatApi.path(`/conversations/${id}/duplicate`),
|
|
534
564
|
chatApi.withChatHeaders({
|
|
535
|
-
method: "POST"
|
|
565
|
+
method: "POST",
|
|
566
|
+
headers: { "Idempotency-Key": idempotencyKey }
|
|
536
567
|
})
|
|
537
568
|
);
|
|
569
|
+
releaseDuplicateKey(requestKey);
|
|
538
570
|
upsertConversationInLoadedBuckets(duplicated, requestRuntimeScope);
|
|
539
571
|
updateConversationCounts(requestRuntimeScope, duplicated, 1);
|
|
540
572
|
statusToast.update({
|
|
@@ -543,13 +575,19 @@ export function useConversations() {
|
|
|
543
575
|
});
|
|
544
576
|
return duplicated;
|
|
545
577
|
} catch (err) {
|
|
578
|
+
const status = err?.statusCode;
|
|
579
|
+
if (status !== void 0 && status >= 400 && status < 500)
|
|
580
|
+
releaseDuplicateKey(requestKey);
|
|
546
581
|
const message = err instanceof Error ? err.message : "Erro ao duplicar conversa";
|
|
547
582
|
error.value = message;
|
|
583
|
+
const code = err?.data?.code;
|
|
548
584
|
statusToast.update({
|
|
549
|
-
text: "Erro ao duplicar conversa",
|
|
585
|
+
text: code === "session_fork_source_running" ? "Aguarde a resposta terminar para duplicar a conversa." : "Erro ao duplicar conversa",
|
|
550
586
|
icon: "i-ph-warning"
|
|
551
587
|
});
|
|
552
588
|
return null;
|
|
589
|
+
} finally {
|
|
590
|
+
duplicatesInFlight.delete(requestKey);
|
|
553
591
|
}
|
|
554
592
|
};
|
|
555
593
|
return {
|
|
@@ -19,27 +19,27 @@ type __VLS_Props = {
|
|
|
19
19
|
user?: EmbedUser | null;
|
|
20
20
|
features?: Partial<ChatFeatureConfig>;
|
|
21
21
|
};
|
|
22
|
-
declare var __VLS_14: {},
|
|
22
|
+
declare var __VLS_14: {}, __VLS_99: {}, __VLS_114: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_127: {}, __VLS_136: {}, __VLS_207: {}, __VLS_228: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_241: {};
|
|
27
27
|
type __VLS_Slots = {} & {
|
|
28
28
|
'sidebar-bottom'?: (props: typeof __VLS_14) => any;
|
|
29
29
|
} & {
|
|
30
|
-
'composer-bottom'?: (props: typeof
|
|
30
|
+
'composer-bottom'?: (props: typeof __VLS_99) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_114) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_127) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_136) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'composer-bottom'?: (props: typeof
|
|
38
|
+
'composer-bottom'?: (props: typeof __VLS_207) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'failed-message-actions'?: (props: typeof
|
|
40
|
+
'failed-message-actions'?: (props: typeof __VLS_228) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'composer-bottom'?: (props: typeof
|
|
42
|
+
'composer-bottom'?: (props: typeof __VLS_241) => any;
|
|
43
43
|
};
|
|
44
44
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
45
45
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -14,6 +14,7 @@ import ChatMobileFilePreview from "./mobile/chat-mobile-file-preview.vue";
|
|
|
14
14
|
import ChatMobileShell from "./mobile/chat-mobile-shell.vue";
|
|
15
15
|
import ChatSidebarToggle from "./chat-sidebar-toggle.vue";
|
|
16
16
|
import ChatDetailsPanel from "./chat-details-panel.vue";
|
|
17
|
+
import ChatForkPreparation from "./chat-fork-preparation.vue";
|
|
17
18
|
import ChatMessageInput from "../../messages/components/chat-message-input.vue";
|
|
18
19
|
import { confirmPendingComposerSend, prepareComposerSend, reconcileComposerSend } from "../../messages/composer-pending-send";
|
|
19
20
|
import { composerDraftStorageKey, readComposerDraft, writeComposerDraft } from "../../messages/composer-draft";
|
|
@@ -600,10 +601,17 @@ const conversationCreator = computed(
|
|
|
600
601
|
getMember
|
|
601
602
|
})
|
|
602
603
|
);
|
|
604
|
+
const pendingFork = computed(() => {
|
|
605
|
+
const fork = currentConversation.value?.fork;
|
|
606
|
+
return fork && fork.status !== "ready" ? fork : null;
|
|
607
|
+
});
|
|
608
|
+
const forkBlocked = computed(() => Boolean(pendingFork.value));
|
|
603
609
|
function claimableWakeSessionId() {
|
|
604
610
|
return agentWake?.state.value === "ready" && !currentConversation.value?.threadSessionId ? agentWake.sessionId.value : void 0;
|
|
605
611
|
}
|
|
606
612
|
async function handleSend(content, files, agentInputs) {
|
|
613
|
+
if (forkBlocked.value)
|
|
614
|
+
return;
|
|
607
615
|
const prepared = composerExtension?.prepareSend?.(content);
|
|
608
616
|
const outbound = prepared?.content ?? content;
|
|
609
617
|
unconfirmedDraft = {
|
|
@@ -705,7 +713,7 @@ if (agentWake && !chatApi.conversationV2Enabled) {
|
|
|
705
713
|
}
|
|
706
714
|
const sendChatMessageFromContent = async (content) => {
|
|
707
715
|
const trimmed = content.trim();
|
|
708
|
-
if (!trimmed || props.composerDisabled || composerLocked.value)
|
|
716
|
+
if (!trimmed || props.composerDisabled || composerLocked.value || forkBlocked.value)
|
|
709
717
|
return false;
|
|
710
718
|
const resolvedAgentInputs = resolveTelaAgentInputs(void 0, embedConfig?.telaAgentInputs?.value);
|
|
711
719
|
return Boolean(await dispatchMessage(trimmed, [], resolvedAgentInputs));
|
|
@@ -715,6 +723,8 @@ async function handleCancel() {
|
|
|
715
723
|
await cancelConversation();
|
|
716
724
|
}
|
|
717
725
|
async function handleRetry(messageId) {
|
|
726
|
+
if (forkBlocked.value)
|
|
727
|
+
return;
|
|
718
728
|
const executionSettings = { model: selectedModel.value, reasoningEffort: selectedReasoningEffort.value };
|
|
719
729
|
await retryMessage(messageId, async () => {
|
|
720
730
|
const conversation = currentConversation.value;
|
|
@@ -848,6 +858,56 @@ watch([
|
|
|
848
858
|
}
|
|
849
859
|
}, { immediate: true });
|
|
850
860
|
const forking = ref(false);
|
|
861
|
+
const isLightweightHarness = computed(() => harnessAdapter?.requiresSandboxWake === false);
|
|
862
|
+
const forkPollError = ref(null);
|
|
863
|
+
async function retryForkPreparation(sourceId) {
|
|
864
|
+
if (forking.value)
|
|
865
|
+
return;
|
|
866
|
+
forking.value = true;
|
|
867
|
+
const origin = currentConversation.value?.id;
|
|
868
|
+
const scope = JSON.stringify(chatApi.withChatHeaders().headers);
|
|
869
|
+
try {
|
|
870
|
+
const duplicated = await duplicateConversation(sourceId, { newAttempt: true });
|
|
871
|
+
if (!duplicated || currentConversation.value?.id !== origin || JSON.stringify(chatApi.withChatHeaders().headers) !== scope)
|
|
872
|
+
return;
|
|
873
|
+
closePreview();
|
|
874
|
+
clearPendingConversationGroup();
|
|
875
|
+
setConversation(duplicated);
|
|
876
|
+
updateConversationId(duplicated.id);
|
|
877
|
+
} finally {
|
|
878
|
+
forking.value = false;
|
|
879
|
+
}
|
|
880
|
+
}
|
|
881
|
+
watch(() => [currentConversation.value?.id, currentConversation.value?.fork?.status, JSON.stringify(chatApi.withChatHeaders().headers)], ([id, status], _, onCleanup) => {
|
|
882
|
+
forkPollError.value = null;
|
|
883
|
+
if (!id || status !== "initializing")
|
|
884
|
+
return;
|
|
885
|
+
let stopped = false;
|
|
886
|
+
let timer;
|
|
887
|
+
const poll = async () => {
|
|
888
|
+
try {
|
|
889
|
+
const conversation = await $fetch(chatApi.path(`/conversations/${id}`), chatApi.withChatHeaders());
|
|
890
|
+
if (stopped || currentConversation.value?.id !== id)
|
|
891
|
+
return;
|
|
892
|
+
forkPollError.value = null;
|
|
893
|
+
if (conversation.fork?.status !== "initializing") {
|
|
894
|
+
setConversation(conversation);
|
|
895
|
+
return;
|
|
896
|
+
}
|
|
897
|
+
} catch {
|
|
898
|
+
if (!stopped)
|
|
899
|
+
forkPollError.value = "N\xE3o foi poss\xEDvel atualizar a prepara\xE7\xE3o. Tentando novamente\u2026";
|
|
900
|
+
}
|
|
901
|
+
if (!stopped)
|
|
902
|
+
timer = setTimeout(poll, 1500);
|
|
903
|
+
};
|
|
904
|
+
onCleanup(() => {
|
|
905
|
+
stopped = true;
|
|
906
|
+
if (timer)
|
|
907
|
+
clearTimeout(timer);
|
|
908
|
+
});
|
|
909
|
+
void poll();
|
|
910
|
+
}, { immediate: true });
|
|
851
911
|
async function handleFork(messageId) {
|
|
852
912
|
const sourceId = currentConversation.value?.id;
|
|
853
913
|
if (!sourceId || forking.value)
|
|
@@ -1092,21 +1152,31 @@ async function handleDelete() {
|
|
|
1092
1152
|
<template #empty>
|
|
1093
1153
|
<TelaChatEmptyState
|
|
1094
1154
|
compact
|
|
1095
|
-
:title="emptyStateLabels.title"
|
|
1096
|
-
:description="emptyStateLabels.description"
|
|
1155
|
+
:title="pendingFork ? void 0 : emptyStateLabels.title"
|
|
1156
|
+
:description="pendingFork ? void 0 : emptyStateLabels.description"
|
|
1097
1157
|
>
|
|
1098
|
-
<
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1158
|
+
<ChatForkPreparation
|
|
1159
|
+
v-if="pendingFork"
|
|
1160
|
+
compact
|
|
1161
|
+
:fork="pendingFork"
|
|
1162
|
+
:poll-error="forkPollError"
|
|
1163
|
+
:retrying="forking"
|
|
1164
|
+
@retry="retryForkPreparation(pendingFork.sourceConversationId)"
|
|
1165
|
+
/>
|
|
1166
|
+
<template v-else>
|
|
1167
|
+
<TelaChatSuggestions v-if="resolvedSuggestions.length">
|
|
1168
|
+
<TelaChatSuggestion
|
|
1169
|
+
v-for="suggestion in resolvedSuggestions"
|
|
1170
|
+
:key="suggestion.title"
|
|
1171
|
+
:suggestion="suggestion.prompt"
|
|
1172
|
+
@click="applySuggestion($event)"
|
|
1173
|
+
>
|
|
1174
|
+
{{ suggestion.title }}
|
|
1175
|
+
</TelaChatSuggestion>
|
|
1176
|
+
</TelaChatSuggestions>
|
|
1108
1177
|
|
|
1109
|
-
|
|
1178
|
+
<TelaChatPromptInputHints v-if="resolvedFeatures.showPromptInputHints" size="sm" :hints="PROMPT_INPUT_HINTS" />
|
|
1179
|
+
</template>
|
|
1110
1180
|
|
|
1111
1181
|
<template #input>
|
|
1112
1182
|
<ChatMessageInput
|
|
@@ -1115,7 +1185,7 @@ async function handleDelete() {
|
|
|
1115
1185
|
v-model:selected-reasoning-effort="selectedReasoningEffort"
|
|
1116
1186
|
:draft-storage-key="draftStorageKey"
|
|
1117
1187
|
:loading="loading || composerLocked"
|
|
1118
|
-
:disabled="composerDisabled"
|
|
1188
|
+
:disabled="composerDisabled || forkBlocked"
|
|
1119
1189
|
:send-blocked="sendBlocked"
|
|
1120
1190
|
:creator-name="currentUser?.name ?? void 0"
|
|
1121
1191
|
:creator-email="
|
|
@@ -1156,8 +1226,9 @@ async function handleDelete() {
|
|
|
1156
1226
|
:show-timestamps="resolvedFeatures.showMessageTimestamps"
|
|
1157
1227
|
:show-ai-mistakes-disclaimer="resolvedFeatures.showAiMistakesDisclaimer"
|
|
1158
1228
|
variant="mobile"
|
|
1159
|
-
:fork-enabled="chatApi.conversationV2Enabled"
|
|
1229
|
+
:fork-enabled="chatApi.conversationV2Enabled && !isLightweightHarness"
|
|
1160
1230
|
:fork-disabled="forking"
|
|
1231
|
+
:retry-disabled="forkBlocked"
|
|
1161
1232
|
@fork="handleFork"
|
|
1162
1233
|
@open-conversation="openConversation"
|
|
1163
1234
|
@retry="handleRetry"
|
|
@@ -1175,7 +1246,7 @@ async function handleDelete() {
|
|
|
1175
1246
|
:draft-storage-key="draftStorageKey"
|
|
1176
1247
|
class="!p-0"
|
|
1177
1248
|
:loading="loading || composerLocked"
|
|
1178
|
-
:disabled="composerDisabled"
|
|
1249
|
+
:disabled="composerDisabled || forkBlocked"
|
|
1179
1250
|
:send-blocked="sendBlocked"
|
|
1180
1251
|
:creator-name="currentUser?.name ?? void 0"
|
|
1181
1252
|
:creator-email="
|
|
@@ -1305,25 +1376,35 @@ async function handleDelete() {
|
|
|
1305
1376
|
<TelaChatEmptyState
|
|
1306
1377
|
v-else-if="!isMobile && !hasMessages"
|
|
1307
1378
|
:compact="compact"
|
|
1308
|
-
:title="emptyStateLabels.title"
|
|
1309
|
-
:description="emptyStateLabels.description"
|
|
1379
|
+
:title="pendingFork ? void 0 : emptyStateLabels.title"
|
|
1380
|
+
:description="pendingFork ? void 0 : emptyStateLabels.description"
|
|
1310
1381
|
>
|
|
1311
|
-
<
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
{{ suggestion.title }}
|
|
1319
|
-
</TelaChatSuggestion>
|
|
1320
|
-
</TelaChatSuggestions>
|
|
1321
|
-
|
|
1322
|
-
<TelaChatPromptInputHints
|
|
1323
|
-
v-if="resolvedFeatures.showPromptInputHints"
|
|
1324
|
-
:size="compact ? 'sm' : 'md'"
|
|
1325
|
-
:hints="PROMPT_INPUT_HINTS"
|
|
1382
|
+
<ChatForkPreparation
|
|
1383
|
+
v-if="pendingFork"
|
|
1384
|
+
:compact="compact"
|
|
1385
|
+
:fork="pendingFork"
|
|
1386
|
+
:poll-error="forkPollError"
|
|
1387
|
+
:retrying="forking"
|
|
1388
|
+
@retry="retryForkPreparation(pendingFork.sourceConversationId)"
|
|
1326
1389
|
/>
|
|
1390
|
+
<template v-else>
|
|
1391
|
+
<TelaChatSuggestions v-if="resolvedSuggestions.length">
|
|
1392
|
+
<TelaChatSuggestion
|
|
1393
|
+
v-for="suggestion in resolvedSuggestions"
|
|
1394
|
+
:key="suggestion.title"
|
|
1395
|
+
:suggestion="suggestion.prompt"
|
|
1396
|
+
@click="applySuggestion($event)"
|
|
1397
|
+
>
|
|
1398
|
+
{{ suggestion.title }}
|
|
1399
|
+
</TelaChatSuggestion>
|
|
1400
|
+
</TelaChatSuggestions>
|
|
1401
|
+
|
|
1402
|
+
<TelaChatPromptInputHints
|
|
1403
|
+
v-if="resolvedFeatures.showPromptInputHints"
|
|
1404
|
+
:size="compact ? 'sm' : 'md'"
|
|
1405
|
+
:hints="PROMPT_INPUT_HINTS"
|
|
1406
|
+
/>
|
|
1407
|
+
</template>
|
|
1327
1408
|
|
|
1328
1409
|
<template #input>
|
|
1329
1410
|
<ChatMessageInput
|
|
@@ -1332,7 +1413,7 @@ async function handleDelete() {
|
|
|
1332
1413
|
v-model:selected-reasoning-effort="selectedReasoningEffort"
|
|
1333
1414
|
:draft-storage-key="draftStorageKey"
|
|
1334
1415
|
:loading="loading || composerLocked"
|
|
1335
|
-
:disabled="composerDisabled"
|
|
1416
|
+
:disabled="composerDisabled || forkBlocked"
|
|
1336
1417
|
:send-blocked="sendBlocked"
|
|
1337
1418
|
:creator-name="currentUser?.name ?? void 0"
|
|
1338
1419
|
:creator-email="
|
|
@@ -1376,8 +1457,9 @@ async function handleDelete() {
|
|
|
1376
1457
|
:show-timestamps="resolvedFeatures.showMessageTimestamps"
|
|
1377
1458
|
:show-ai-mistakes-disclaimer="resolvedFeatures.showAiMistakesDisclaimer"
|
|
1378
1459
|
:variant="compact ? 'widget' : 'page'"
|
|
1379
|
-
:fork-enabled="chatApi.conversationV2Enabled"
|
|
1460
|
+
:fork-enabled="chatApi.conversationV2Enabled && !isLightweightHarness"
|
|
1380
1461
|
:fork-disabled="forking"
|
|
1462
|
+
:retry-disabled="forkBlocked"
|
|
1381
1463
|
@fork="handleFork"
|
|
1382
1464
|
@open-conversation="openConversation"
|
|
1383
1465
|
@retry="handleRetry"
|
|
@@ -1395,7 +1477,7 @@ async function handleDelete() {
|
|
|
1395
1477
|
:draft-storage-key="draftStorageKey"
|
|
1396
1478
|
class="!p-0"
|
|
1397
1479
|
:loading="loading || composerLocked"
|
|
1398
|
-
:disabled="composerDisabled"
|
|
1480
|
+
:disabled="composerDisabled || forkBlocked"
|
|
1399
1481
|
:send-blocked="sendBlocked"
|
|
1400
1482
|
:creator-name="currentUser?.name ?? void 0"
|
|
1401
1483
|
:creator-email="
|
|
@@ -19,27 +19,27 @@ type __VLS_Props = {
|
|
|
19
19
|
user?: EmbedUser | null;
|
|
20
20
|
features?: Partial<ChatFeatureConfig>;
|
|
21
21
|
};
|
|
22
|
-
declare var __VLS_14: {},
|
|
22
|
+
declare var __VLS_14: {}, __VLS_99: {}, __VLS_114: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_127: {}, __VLS_136: {}, __VLS_207: {}, __VLS_228: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_241: {};
|
|
27
27
|
type __VLS_Slots = {} & {
|
|
28
28
|
'sidebar-bottom'?: (props: typeof __VLS_14) => any;
|
|
29
29
|
} & {
|
|
30
|
-
'composer-bottom'?: (props: typeof
|
|
30
|
+
'composer-bottom'?: (props: typeof __VLS_99) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_114) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_127) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_136) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'composer-bottom'?: (props: typeof
|
|
38
|
+
'composer-bottom'?: (props: typeof __VLS_207) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'failed-message-actions'?: (props: typeof
|
|
40
|
+
'failed-message-actions'?: (props: typeof __VLS_228) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'composer-bottom'?: (props: typeof
|
|
42
|
+
'composer-bottom'?: (props: typeof __VLS_241) => any;
|
|
43
43
|
};
|
|
44
44
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
45
45
|
"update:conversationId": (value: string | null) => any;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ConversationFork } from '../../types/schemas/chat/conversations.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
fork: ConversationFork;
|
|
4
|
+
compact?: boolean;
|
|
5
|
+
pollError?: string | null;
|
|
6
|
+
retrying?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
retry: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
onRetry?: (() => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
const props = defineProps({
|
|
3
|
+
fork: { type: null, required: true },
|
|
4
|
+
compact: { type: Boolean, required: false },
|
|
5
|
+
pollError: { type: [String, null], required: false },
|
|
6
|
+
retrying: { type: Boolean, required: false }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["retry"]);
|
|
9
|
+
const failed = computed(() => props.fork.status === "failed");
|
|
10
|
+
const failureReason = computed(() => {
|
|
11
|
+
switch (props.fork.error) {
|
|
12
|
+
case "session_fork_restore_failed":
|
|
13
|
+
return "Alguns arquivos ou dados da conversa original n\xE3o puderam ser copiados.";
|
|
14
|
+
case "session_fork_checkpoint_unavailable":
|
|
15
|
+
return "O estado mais recente da conversa original n\xE3o est\xE1 dispon\xEDvel.";
|
|
16
|
+
default:
|
|
17
|
+
return "A prepara\xE7\xE3o foi interrompida.";
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<div role="status" aria-live="polite" flex="~ col" items-center gap-16px text-center>
|
|
24
|
+
<div size-40px rounded-12px bg-neutral-100 flex items-center justify-center>
|
|
25
|
+
<span v-if="failed" i-ph-warning-circle text-20px text-red-600 />
|
|
26
|
+
<span v-else i-ph-spinner animate-spin text-20px text-neutral-500 />
|
|
27
|
+
</div>
|
|
28
|
+
<div flex="~ col" items-center gap-4px>
|
|
29
|
+
<component :is="compact ? 'h5' : 'h1'" text-primary :class="compact ? 'heading-h4-semibold' : 'heading-h3-semibold'">
|
|
30
|
+
{{ failed ? "N\xE3o foi poss\xEDvel preparar a c\xF3pia" : "Preparando a c\xF3pia" }}
|
|
31
|
+
</component>
|
|
32
|
+
<p text-secondary body-14-regular max-w-440px>
|
|
33
|
+
<template v-if="failed">
|
|
34
|
+
{{ failureReason }} Tente novamente para criar uma nova cópia.
|
|
35
|
+
</template>
|
|
36
|
+
<template v-else>
|
|
37
|
+
Copiando o histórico, os arquivos e o contexto da conversa original. Você poderá continuar em instantes.
|
|
38
|
+
</template>
|
|
39
|
+
</p>
|
|
40
|
+
<p v-if="!failed && pollError" text-secondary body-12-regular>
|
|
41
|
+
{{ pollError }}
|
|
42
|
+
</p>
|
|
43
|
+
</div>
|
|
44
|
+
<TelaButton v-if="failed" size="sm" variant="secondary" :disabled="retrying" @click="emit('retry')">
|
|
45
|
+
Tentar novamente
|
|
46
|
+
</TelaButton>
|
|
47
|
+
</div>
|
|
48
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ConversationFork } from '../../types/schemas/chat/conversations.js';
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
fork: ConversationFork;
|
|
4
|
+
compact?: boolean;
|
|
5
|
+
pollError?: string | null;
|
|
6
|
+
retrying?: boolean;
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
retry: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
onRetry?: (() => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -31,6 +31,7 @@ const eventTime = computed(() => new Intl.DateTimeFormat("pt-BR", {
|
|
|
31
31
|
<p v-if="forkSource" body-12-regular text-secondary text-center min-w-0>
|
|
32
32
|
Conversa iniciada a partir de
|
|
33
33
|
<NuxtLink
|
|
34
|
+
v-if="forkSource.sourceAccessible !== false"
|
|
34
35
|
:to="sourceLocation"
|
|
35
36
|
body-12-medium
|
|
36
37
|
underline
|
|
@@ -39,6 +40,7 @@ const eventTime = computed(() => new Intl.DateTimeFormat("pt-BR", {
|
|
|
39
40
|
>
|
|
40
41
|
{{ forkSource.sourceTitle }}
|
|
41
42
|
</NuxtLink>
|
|
43
|
+
<span v-else>{{ forkSource.sourceTitle }}</span>
|
|
42
44
|
</p>
|
|
43
45
|
<p v-else body-12-regular text-tertiary text-center>
|
|
44
46
|
<span v-if="event.actorLabel" body-12-medium text-secondary>{{ event.actorLabel }}</span>
|
|
@@ -21,7 +21,8 @@ const props = defineProps({
|
|
|
21
21
|
showTtft: { type: Boolean, required: false, default: true },
|
|
22
22
|
showTimestamps: { type: Boolean, required: false, default: true },
|
|
23
23
|
forkEnabled: { type: Boolean, required: false },
|
|
24
|
-
forkDisabled: { type: Boolean, required: false }
|
|
24
|
+
forkDisabled: { type: Boolean, required: false },
|
|
25
|
+
retryDisabled: { type: Boolean, required: false }
|
|
25
26
|
});
|
|
26
27
|
const emit = defineEmits(["retry", "fork"]);
|
|
27
28
|
defineSlots();
|
|
@@ -170,24 +171,29 @@ const attachedFiles = computed(() => {
|
|
|
170
171
|
:class="[isPending && 'op-80']"
|
|
171
172
|
>
|
|
172
173
|
<div v-if="hasFiles" flex="~ col" gap-4px mb-8px>
|
|
173
|
-
<
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
174
|
+
<template v-for="file in message.files" :key="file.url">
|
|
175
|
+
<ChatFilePreview
|
|
176
|
+
v-if="file.url.startsWith('vault://')"
|
|
177
|
+
:file="{ type: 'vault', reference: file.url, name: file.name, mimeType: file.mimeType ?? 'unknown' }"
|
|
178
|
+
/>
|
|
179
|
+
<a
|
|
180
|
+
v-else
|
|
181
|
+
:href="file.url"
|
|
182
|
+
target="_blank"
|
|
183
|
+
rel="noopener noreferrer"
|
|
184
|
+
flex
|
|
185
|
+
items-center
|
|
186
|
+
gap-6px
|
|
187
|
+
body-12-regular
|
|
188
|
+
text-gray-600
|
|
189
|
+
op-80
|
|
190
|
+
hover:op-100
|
|
191
|
+
transition-opacity
|
|
192
|
+
>
|
|
193
|
+
<span i-ph-paperclip text-14px />
|
|
194
|
+
<span truncate max-w-200px>{{ file.name }}</span>
|
|
195
|
+
</a>
|
|
196
|
+
</template>
|
|
191
197
|
</div>
|
|
192
198
|
<div body-16-regular whitespace-pre-wrap break-words>
|
|
193
199
|
<template v-for="(segment, index) in userContentSegments" :key="`${index}-${segment.type === 'citation' ? segment.citation.raw : 'text'}`">
|
|
@@ -264,6 +270,7 @@ const attachedFiles = computed(() => {
|
|
|
264
270
|
text-13px text-gray-700
|
|
265
271
|
transition-colors
|
|
266
272
|
cursor-pointer
|
|
273
|
+
:disabled="retryDisabled"
|
|
267
274
|
@click="emit('retry', message.id)"
|
|
268
275
|
>
|
|
269
276
|
<div i-ph-arrow-clockwise text-14px />
|
|
@@ -16,7 +16,8 @@ const props = defineProps({
|
|
|
16
16
|
showTimestamps: { type: Boolean, required: false, default: true },
|
|
17
17
|
showAiMistakesDisclaimer: { type: Boolean, required: false, default: true },
|
|
18
18
|
forkEnabled: { type: Boolean, required: false },
|
|
19
|
-
forkDisabled: { type: Boolean, required: false }
|
|
19
|
+
forkDisabled: { type: Boolean, required: false },
|
|
20
|
+
retryDisabled: { type: Boolean, required: false }
|
|
20
21
|
});
|
|
21
22
|
const emit = defineEmits(["retry", "fork", "openConversation"]);
|
|
22
23
|
defineSlots();
|
|
@@ -145,6 +146,7 @@ defineExpose({
|
|
|
145
146
|
:show-timestamps="showTimestamps"
|
|
146
147
|
:fork-enabled="forkEnabled"
|
|
147
148
|
:fork-disabled="forkDisabled"
|
|
149
|
+
:retry-disabled="retryDisabled"
|
|
148
150
|
@fork="emit('fork', $event)"
|
|
149
151
|
@retry="emit('retry', $event)"
|
|
150
152
|
>
|
|
@@ -4,6 +4,7 @@ export declare function getConversationForkSource(event: ConversationEvent): {
|
|
|
4
4
|
sourceConversationId: string;
|
|
5
5
|
sourceTitle: string;
|
|
6
6
|
copiedMessageId: string;
|
|
7
|
+
sourceAccessible?: boolean | undefined;
|
|
7
8
|
} | null;
|
|
8
9
|
export type ConversationTimelineItem = {
|
|
9
10
|
kind: 'event';
|
|
@@ -4,6 +4,7 @@ import { resolveChatExecutionMode } from "../embed/execution-controls.js";
|
|
|
4
4
|
const forkSourceSchema = z.object({
|
|
5
5
|
sourceConversationId: z.string().uuid(),
|
|
6
6
|
sourceTitle: z.string(),
|
|
7
|
+
sourceAccessible: z.boolean().optional(),
|
|
7
8
|
copiedMessageId: z.string().uuid()
|
|
8
9
|
});
|
|
9
10
|
export function getConversationForkSource(event) {
|
|
@@ -41,13 +42,21 @@ export function mergeConversationTimeline(messages, events = [], controls) {
|
|
|
41
42
|
const targetIndex = items.findIndex((candidate) => candidate.kind === "message" && candidate.id === item.value.payload.messageId);
|
|
42
43
|
items.splice(targetIndex, 0, item);
|
|
43
44
|
}
|
|
45
|
+
const forkMarkers = /* @__PURE__ */ new Map();
|
|
44
46
|
for (const event of events ?? []) {
|
|
45
47
|
const source = getConversationForkSource(event);
|
|
46
48
|
if (!source)
|
|
47
49
|
continue;
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
const markers = forkMarkers.get(source.copiedMessageId) ?? [];
|
|
51
|
+
markers.push({ kind: "event", id: event.id, createdAt: event.createdAt, value: event });
|
|
52
|
+
forkMarkers.set(source.copiedMessageId, markers);
|
|
53
|
+
}
|
|
54
|
+
for (const [messageId, markers] of forkMarkers) {
|
|
55
|
+
const index = items.findIndex((item) => item.kind === "message" && item.id === messageId);
|
|
56
|
+
if (index !== -1) {
|
|
57
|
+
markers.sort((left, right) => new Date(left.createdAt).getTime() - new Date(right.createdAt).getTime() || left.id.localeCompare(right.id));
|
|
58
|
+
items.splice(index + 1, 0, ...markers);
|
|
59
|
+
}
|
|
51
60
|
}
|
|
52
61
|
if (controls?.mode === "simple") {
|
|
53
62
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AGENT_API_V5_CONFIG_KEY, PRE_WAKE_CACHE_CONFIG_KEY, CONVERSATION_V2_CONFIG_KEY, PREPARED_AGENT_RUNTIME_CONFIG_KEY, ROUTE_CLAUDE_VIA_GATEWAY_CONFIG_KEY, SECRETLESS_EXECUTION_CONFIG_KEY, UI_LANGUAGE_CONFIG_KEY } from "../../types/schemas/chat/chat-config.js";
|
|
1
|
+
import { AGENT_API_V5_CONFIG_KEY, LIGHTWEIGHT_SESSION_FORK_CONFIG_KEY, PRE_WAKE_CACHE_CONFIG_KEY, CONVERSATION_V2_CONFIG_KEY, PREPARED_AGENT_RUNTIME_CONFIG_KEY, ROUTE_CLAUDE_VIA_GATEWAY_CONFIG_KEY, SECRETLESS_EXECUTION_CONFIG_KEY, UI_LANGUAGE_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";
|
|
@@ -99,6 +99,9 @@ function buildProxyHeaders(event) {
|
|
|
99
99
|
if (config.chatNuxt?.secretlessExecution) {
|
|
100
100
|
chatConfig[SECRETLESS_EXECUTION_CONFIG_KEY] = true;
|
|
101
101
|
}
|
|
102
|
+
if (config.chatNuxt?.lightweightSessionFork === true) {
|
|
103
|
+
chatConfig[LIGHTWEIGHT_SESSION_FORK_CONFIG_KEY] = true;
|
|
104
|
+
}
|
|
102
105
|
if (config.chatNuxt?.preWakeCache === true) {
|
|
103
106
|
chatConfig[PRE_WAKE_CACHE_CONFIG_KEY] = true;
|
|
104
107
|
}
|
|
@@ -3,6 +3,7 @@ export declare const PREPARED_AGENT_RUNTIME_CONFIG_KEY = "prepared-agent-runtime
|
|
|
3
3
|
export declare const SECRETLESS_EXECUTION_CONFIG_KEY = "secretless-execution";
|
|
4
4
|
export declare const AGENT_API_V5_CONFIG_KEY = "agent-api-v5";
|
|
5
5
|
export declare const CONVERSATION_V2_CONFIG_KEY = "conversation-v2";
|
|
6
|
+
export declare const LIGHTWEIGHT_SESSION_FORK_CONFIG_KEY = "lightweight-session-fork";
|
|
6
7
|
export declare const PRE_WAKE_CACHE_CONFIG_KEY = "pre-wake-cache";
|
|
7
8
|
export declare const ROUTE_CLAUDE_VIA_GATEWAY_CONFIG_KEY = "route-claude-via-gateway";
|
|
8
9
|
export type ChatHarness = 'claude' | 'lightweight';
|
|
@@ -2,6 +2,7 @@ export const PREPARED_AGENT_RUNTIME_CONFIG_KEY = 'prepared-agent-runtime';
|
|
|
2
2
|
export const SECRETLESS_EXECUTION_CONFIG_KEY = 'secretless-execution';
|
|
3
3
|
export const AGENT_API_V5_CONFIG_KEY = 'agent-api-v5';
|
|
4
4
|
export const CONVERSATION_V2_CONFIG_KEY = 'conversation-v2';
|
|
5
|
+
export const LIGHTWEIGHT_SESSION_FORK_CONFIG_KEY = 'lightweight-session-fork';
|
|
5
6
|
export const PRE_WAKE_CACHE_CONFIG_KEY = 'pre-wake-cache';
|
|
6
7
|
export const ROUTE_CLAUDE_VIA_GATEWAY_CONFIG_KEY = 'route-claude-via-gateway';
|
|
7
8
|
export function resolveChatHarness(config) {
|
|
@@ -206,6 +206,17 @@ export declare const sendMessageV2ResponseSchema: z.ZodObject<{
|
|
|
206
206
|
waiting_messages: "waiting_messages";
|
|
207
207
|
blocked: "blocked";
|
|
208
208
|
}>;
|
|
209
|
+
fork: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
210
|
+
sourceConversationId: z.ZodString;
|
|
211
|
+
baseSessionId: z.ZodString;
|
|
212
|
+
checkpointId: z.ZodNullable<z.ZodString>;
|
|
213
|
+
status: z.ZodEnum<{
|
|
214
|
+
failed: "failed";
|
|
215
|
+
ready: "ready";
|
|
216
|
+
initializing: "initializing";
|
|
217
|
+
}>;
|
|
218
|
+
error: z.ZodNullable<z.ZodString>;
|
|
219
|
+
}, z.core.$strip>>>;
|
|
209
220
|
}, z.core.$strip>;
|
|
210
221
|
}, z.core.$strip>;
|
|
211
222
|
export type SendMessageV2Response = z.infer<typeof sendMessageV2ResponseSchema>;
|
|
@@ -215,6 +226,17 @@ export declare const conversationRuntimeV2ResponseSchema: z.ZodObject<{
|
|
|
215
226
|
waiting_messages: "waiting_messages";
|
|
216
227
|
blocked: "blocked";
|
|
217
228
|
}>;
|
|
229
|
+
fork: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
230
|
+
sourceConversationId: z.ZodString;
|
|
231
|
+
baseSessionId: z.ZodString;
|
|
232
|
+
checkpointId: z.ZodNullable<z.ZodString>;
|
|
233
|
+
status: z.ZodEnum<{
|
|
234
|
+
failed: "failed";
|
|
235
|
+
ready: "ready";
|
|
236
|
+
initializing: "initializing";
|
|
237
|
+
}>;
|
|
238
|
+
error: z.ZodNullable<z.ZodString>;
|
|
239
|
+
}, z.core.$strip>>>;
|
|
218
240
|
}, z.core.$strip>;
|
|
219
241
|
turn: z.ZodNullable<z.ZodObject<{
|
|
220
242
|
id: z.ZodString;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { telaAgentExecutionInputSchema } from '../integrations/tela-agent-api';
|
|
3
|
-
import { messageSchema } from './conversations';
|
|
3
|
+
import { conversationForkSchema, messageSchema } from './conversations';
|
|
4
4
|
import { fileUploadInputSchema } from './files';
|
|
5
5
|
import { executionSettingsSchema, sendMessageClientTimingSchema } from './messages';
|
|
6
6
|
export const conversationRuntimeStateSchema = z.enum(['blocked', 'waiting_messages']);
|
|
@@ -39,10 +39,10 @@ export const sendMessageV2ResponseSchema = z.object({
|
|
|
39
39
|
userMessage: messageSchema,
|
|
40
40
|
assistantMessage: messageSchema,
|
|
41
41
|
turn: turnSnapshotSchema.nullable(),
|
|
42
|
-
conversation: z.object({ runtimeState: conversationRuntimeStateSchema }),
|
|
42
|
+
conversation: z.object({ runtimeState: conversationRuntimeStateSchema, fork: conversationForkSchema.nullable().optional() }),
|
|
43
43
|
});
|
|
44
44
|
export const conversationRuntimeV2ResponseSchema = z.object({
|
|
45
|
-
conversation: z.object({ runtimeState: conversationRuntimeStateSchema }),
|
|
45
|
+
conversation: z.object({ runtimeState: conversationRuntimeStateSchema, fork: conversationForkSchema.nullable().optional() }),
|
|
46
46
|
turn: turnSnapshotSchema.nullable(),
|
|
47
47
|
});
|
|
48
48
|
export const cancelConversationV2ResponseSchema = z.object({
|
|
@@ -1,5 +1,28 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
+
export declare const conversationForkSchema: z.ZodObject<{
|
|
3
|
+
sourceConversationId: z.ZodString;
|
|
4
|
+
baseSessionId: z.ZodString;
|
|
5
|
+
checkpointId: z.ZodNullable<z.ZodString>;
|
|
6
|
+
status: z.ZodEnum<{
|
|
7
|
+
failed: "failed";
|
|
8
|
+
ready: "ready";
|
|
9
|
+
initializing: "initializing";
|
|
10
|
+
}>;
|
|
11
|
+
error: z.ZodNullable<z.ZodString>;
|
|
12
|
+
}, z.core.$strip>;
|
|
13
|
+
export type ConversationFork = z.infer<typeof conversationForkSchema>;
|
|
2
14
|
export declare const conversationSchema: z.ZodObject<{
|
|
15
|
+
fork: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
16
|
+
sourceConversationId: z.ZodString;
|
|
17
|
+
baseSessionId: z.ZodString;
|
|
18
|
+
checkpointId: z.ZodNullable<z.ZodString>;
|
|
19
|
+
status: z.ZodEnum<{
|
|
20
|
+
failed: "failed";
|
|
21
|
+
ready: "ready";
|
|
22
|
+
initializing: "initializing";
|
|
23
|
+
}>;
|
|
24
|
+
error: z.ZodNullable<z.ZodString>;
|
|
25
|
+
}, z.core.$strip>>>;
|
|
3
26
|
id: z.ZodString;
|
|
4
27
|
workspaceId: z.ZodString;
|
|
5
28
|
groupId: z.ZodNullable<z.ZodString>;
|
|
@@ -138,6 +161,17 @@ export declare const conversationListMetadataSchema: z.ZodObject<{
|
|
|
138
161
|
}, z.core.$strip>;
|
|
139
162
|
export type ConversationListMetadata = z.infer<typeof conversationListMetadataSchema>;
|
|
140
163
|
export declare const conversationWithMessagesSchema: z.ZodObject<{
|
|
164
|
+
fork: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
165
|
+
sourceConversationId: z.ZodString;
|
|
166
|
+
baseSessionId: z.ZodString;
|
|
167
|
+
checkpointId: z.ZodNullable<z.ZodString>;
|
|
168
|
+
status: z.ZodEnum<{
|
|
169
|
+
failed: "failed";
|
|
170
|
+
ready: "ready";
|
|
171
|
+
initializing: "initializing";
|
|
172
|
+
}>;
|
|
173
|
+
error: z.ZodNullable<z.ZodString>;
|
|
174
|
+
}, z.core.$strip>>>;
|
|
141
175
|
id: z.ZodString;
|
|
142
176
|
workspaceId: z.ZodString;
|
|
143
177
|
groupId: z.ZodNullable<z.ZodString>;
|
|
@@ -6,7 +6,15 @@ import { chatModelSchema, chatReasoningEffortSchema } from './models';
|
|
|
6
6
|
import { chatModelSchema as lightweightModelSchema } from './lightweight-models';
|
|
7
7
|
import { conversationCreatorFilterSchema, messageRoleSchema, messageStatusSchema, } from './primitives';
|
|
8
8
|
import { resolvedWorkspaceSettingsSchema } from './workspace-settings';
|
|
9
|
+
export const conversationForkSchema = z.object({
|
|
10
|
+
sourceConversationId: z.string(),
|
|
11
|
+
baseSessionId: z.string(),
|
|
12
|
+
checkpointId: z.string().nullable(),
|
|
13
|
+
status: z.enum(['initializing', 'ready', 'failed']),
|
|
14
|
+
error: z.string().nullable(),
|
|
15
|
+
});
|
|
9
16
|
export const conversationSchema = z.object({
|
|
17
|
+
fork: conversationForkSchema.nullable().optional(),
|
|
10
18
|
id: z.string(),
|
|
11
19
|
workspaceId: z.string(),
|
|
12
20
|
groupId: z.string().nullable(),
|