@meistrari/chat-nuxt 3.14.2-rc.2 → 3.15.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/dist/module.d.mts +1 -1
- package/dist/module.json +1 -1
- package/dist/runtime/conversations/composables/conversations.js +37 -25
- package/dist/runtime/embed/components/chat-embed-inner.vue +65 -32
- package/dist/runtime/embed/components/chat-embed.vue +2 -0
- package/dist/runtime/embed/components/meistrari-chat-embed.d.vue.ts +2 -2
- package/dist/runtime/embed/components/meistrari-chat-embed.vue +2 -0
- package/dist/runtime/embed/components/meistrari-chat-embed.vue.d.ts +2 -2
- package/dist/runtime/embed/composables/embed-config.d.ts +3 -0
- package/dist/runtime/embed/composables/embed-config.js +4 -0
- package/dist/runtime/embed/types.d.ts +8 -0
- package/dist/runtime/messages/components/chat-model-selector.vue +23 -12
- package/dist/runtime/messages/composables/chat.d.ts +1 -1
- package/dist/runtime/messages/composables/chat.js +73 -43
- package/dist/runtime/messages/model-availability.d.ts +6 -0
- package/dist/runtime/messages/model-availability.js +28 -0
- package/dist/runtime/server/api/chat/conversations/generate-title.d.ts +2 -0
- package/dist/runtime/server/api/chat/conversations/generate-title.js +3 -0
- package/dist/runtime/server/api/chat/conversations/groups/[groupId].d.ts +2 -0
- package/dist/runtime/server/api/chat/conversations/groups/[groupId].js +6 -0
- package/dist/runtime/server/api/chat/conversations/groups.d.ts +2 -0
- package/dist/runtime/server/api/chat/conversations/groups.js +3 -0
- package/dist/runtime/server/api/chat/conversations/metadata.d.ts +2 -0
- package/dist/runtime/server/api/chat/conversations/metadata.js +3 -0
- package/dist/runtime/types/embed.d.ts +1 -1
- package/dist/runtime/types/schemas/chat/conversations.d.ts +2 -0
- package/dist/runtime/types/schemas/chat/models.d.ts +2 -1
- package/dist/runtime/types/schemas/chat/models.js +1 -0
- package/dist/runtime/types/schemas/chat/ui.d.ts +10 -0
- package/dist/runtime/types/schemas/chat/ui.js +1 -0
- package/dist/runtime/types/schemas/integrations/tela-agent-api.d.ts +1 -0
- package/dist/types.d.mts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,6 +55,7 @@ Declared in `src/runtime/embed/types.ts`; prop, feature-flag, and event payload
|
|
|
55
55
|
| `initialConversationId` | `string \| null` | `null` | Conversation to open once on mount when `conversationId` is uncontrolled |
|
|
56
56
|
| `conversationScope` | `string \| null` | `null` | Isolate conversation history by technical scope within the current workspace and runtime. Scoped embeds only see same-scope conversations; values are trimmed, blank becomes `null`, and the server accepts 1-200 chars from `A-Z`, `a-z`, `0-9`, `.`, `_`, `:`, `/`, `-` |
|
|
57
57
|
| `defaultConversationCreatorFilter` | `'all' \| 'mine'` | `'all'` | Initial sidebar creator filter: every conversation in scope, or only the current user's |
|
|
58
|
+
| `availableModels` | `AvailableChatModels` | Full catalog | Non-empty ordered list of models this embed may display and execute. A missing or invalid restored selection falls back to the first entry; an empty list fails fast |
|
|
58
59
|
| `conversationCreatorFilter` | `'all' \| 'mine'` | — | Controlled sidebar creator filter; use with `v-model:conversation-creator-filter` when the host changes it at runtime |
|
|
59
60
|
| `hideConversationCreatorFilter` | `boolean` | `false` | Hide the creator selector without changing the active filter |
|
|
60
61
|
| `telaAgentId` | `string` | — | Use Tela agent mode for this embed |
|
package/dist/module.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { ChatMessageStatus } from '../dist/runtime/messages/composables/chat-message-terminal.js';
|
|
2
|
-
export { ChatActionPayload, ChatActor, ChatEmbedSharedProps, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, MessageFeedbackSubmitHandler, MessageFeedbackSubmitResult, MessageOverviewResponse, TelaAgentChatEmbedProps, TelaAgentExecutionInput } from '../dist/runtime/types/embed.js';
|
|
2
|
+
export { AvailableChatModels, ChatActionPayload, ChatActor, ChatEmbedSharedProps, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackConfig, MessageFeedbackPayload, MessageFeedbackRating, MessageFeedbackSubmitHandler, MessageFeedbackSubmitResult, MessageOverviewResponse, TelaAgentChatEmbedProps, TelaAgentExecutionInput } from '../dist/runtime/types/embed.js';
|
|
3
3
|
|
|
4
4
|
type ChatNuxtConfigValidationMode = false | 'warn' | 'error';
|
|
5
5
|
|
package/dist/module.json
CHANGED
|
@@ -56,6 +56,7 @@ function createOptimisticConversationId() {
|
|
|
56
56
|
return `optimistic-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
57
57
|
}
|
|
58
58
|
export function useConversations() {
|
|
59
|
+
const nuxtApp = useNuxtApp();
|
|
59
60
|
const chatApi = useChatApi();
|
|
60
61
|
const embedConfig = useEmbedConfig();
|
|
61
62
|
const { user: authUser, activeOrganization } = useChatAuth();
|
|
@@ -69,6 +70,7 @@ export function useConversations() {
|
|
|
69
70
|
const metadataBuckets = useState("conversations-metadata", () => ({}));
|
|
70
71
|
const metadataLoadingBuckets = useState("conversations-metadata-loading", () => ({}));
|
|
71
72
|
const metadataFetchedBuckets = useState("conversations-metadata-fetched", () => ({}));
|
|
73
|
+
const modelUpdateTails = nuxtApp._chatConversationModelUpdateTails ??= /* @__PURE__ */ new Map();
|
|
72
74
|
const providedConversationCreatorFilter = useProvidedConversationCreatorFilterState();
|
|
73
75
|
const conversationCreatorFilter = providedConversationCreatorFilter ?? useState(
|
|
74
76
|
"conversation-creator-filter",
|
|
@@ -462,31 +464,41 @@ export function useConversations() {
|
|
|
462
464
|
return false;
|
|
463
465
|
}
|
|
464
466
|
};
|
|
465
|
-
const updateConversationModel =
|
|
466
|
-
|
|
467
|
-
const
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
467
|
+
const updateConversationModel = (id, model) => {
|
|
468
|
+
const previousUpdate = modelUpdateTails.get(id) ?? Promise.resolve(true);
|
|
469
|
+
const update = previousUpdate.catch(() => false).then(async () => {
|
|
470
|
+
error.value = null;
|
|
471
|
+
const requestRuntimeScope = runtimeScope.value;
|
|
472
|
+
const affectedScopes = activeAndLoadedRuntimeConversationScopes(requestRuntimeScope);
|
|
473
|
+
const conversationSnapshot = snapshotConversationBuckets(affectedScopes);
|
|
474
|
+
const conversation = findConversationInLoadedBuckets(id, requestRuntimeScope);
|
|
475
|
+
if (conversation)
|
|
476
|
+
updateConversationInLoadedBuckets({ ...conversation, model, updatedAt: /* @__PURE__ */ new Date() }, requestRuntimeScope);
|
|
477
|
+
try {
|
|
478
|
+
const updated = await $fetch(
|
|
479
|
+
chatApi.path(`/conversations/${id}`),
|
|
480
|
+
chatApi.withChatHeaders({
|
|
481
|
+
method: "PATCH",
|
|
482
|
+
body: { model }
|
|
483
|
+
})
|
|
484
|
+
);
|
|
485
|
+
updateConversationInLoadedBuckets(updated, requestRuntimeScope);
|
|
486
|
+
return true;
|
|
487
|
+
} catch (err) {
|
|
488
|
+
restoreConversationBuckets(conversationSnapshot, id);
|
|
489
|
+
const message = err instanceof Error ? err.message : "Erro ao atualizar modelo da conversa";
|
|
490
|
+
error.value = message;
|
|
491
|
+
Sentry.captureException(err);
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
});
|
|
495
|
+
const clearUpdate = () => {
|
|
496
|
+
if (modelUpdateTails.get(id) === update)
|
|
497
|
+
modelUpdateTails.delete(id);
|
|
498
|
+
};
|
|
499
|
+
modelUpdateTails.set(id, update);
|
|
500
|
+
void update.then(clearUpdate, clearUpdate);
|
|
501
|
+
return update;
|
|
490
502
|
};
|
|
491
503
|
const duplicateConversation = async (id) => {
|
|
492
504
|
error.value = null;
|
|
@@ -15,6 +15,11 @@ import {
|
|
|
15
15
|
resolveTelaAgentInputs,
|
|
16
16
|
useChat
|
|
17
17
|
} from "../../messages/composables/chat";
|
|
18
|
+
import {
|
|
19
|
+
ensureConversationUsesSelectedModel,
|
|
20
|
+
MODEL_UPDATE_FAILED_MESSAGE,
|
|
21
|
+
resolveChatModelSelection
|
|
22
|
+
} from "../../messages/model-availability";
|
|
18
23
|
import { useChatAction } from "../../messages/composables/chat-action";
|
|
19
24
|
import { useChatApi } from "../../shared/composables/chat-api";
|
|
20
25
|
import { useConversationFiles } from "../../files/composables/conversation-files";
|
|
@@ -201,30 +206,45 @@ watch(chatError, (message) => {
|
|
|
201
206
|
});
|
|
202
207
|
const conversationIdRef = computed(() => currentConversation.value?.id ?? null);
|
|
203
208
|
const { total, files: conversationFiles } = useConversationFiles(conversationIdRef);
|
|
209
|
+
function persistConversationModel(conversation, value, wakeAgent) {
|
|
210
|
+
const previousModel = conversation.model;
|
|
211
|
+
setConversationModel(value);
|
|
212
|
+
const update = updateConversationModel(conversation.id, value).then(async (updated) => {
|
|
213
|
+
if (!updated && currentConversation.value?.id === conversation.id && currentConversation.value.model === value) {
|
|
214
|
+
setConversationModel(previousModel);
|
|
215
|
+
} else if (updated && value && wakeAgent) {
|
|
216
|
+
if (conversation.threadSessionId)
|
|
217
|
+
await agentWake.ensureReady(conversation.threadSessionId, value);
|
|
218
|
+
else
|
|
219
|
+
await agentWake.wake(void 0, value);
|
|
220
|
+
}
|
|
221
|
+
return updated;
|
|
222
|
+
});
|
|
223
|
+
const trackedUpdate = update.finally(() => {
|
|
224
|
+
if (modelUpdateInFlight.value === trackedUpdate)
|
|
225
|
+
modelUpdateInFlight.value = null;
|
|
226
|
+
});
|
|
227
|
+
modelUpdateInFlight.value = trackedUpdate;
|
|
228
|
+
return trackedUpdate;
|
|
229
|
+
}
|
|
230
|
+
async function waitForPendingModelUpdate() {
|
|
231
|
+
while (modelUpdateInFlight.value) {
|
|
232
|
+
const update = modelUpdateInFlight.value;
|
|
233
|
+
if (!await update)
|
|
234
|
+
throw new Error(MODEL_UPDATE_FAILED_MESSAGE);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
204
237
|
const selectedModel = computed({
|
|
205
|
-
get: () =>
|
|
238
|
+
get: () => resolveChatModelSelection(
|
|
239
|
+
currentConversation.value ? currentConversation.value.model : pendingModelSelection.value,
|
|
240
|
+
embedConfig?.availableModels.value
|
|
241
|
+
),
|
|
206
242
|
set: (value) => {
|
|
207
|
-
|
|
243
|
+
const resolvedValue = resolveChatModelSelection(value, embedConfig?.availableModels.value);
|
|
244
|
+
pendingModelSelection.value = resolvedValue;
|
|
208
245
|
const conversation = currentConversation.value;
|
|
209
|
-
if (conversation && conversation.model !==
|
|
210
|
-
|
|
211
|
-
setConversationModel(value);
|
|
212
|
-
const update = updateConversationModel(conversation.id, value).then(async (updated) => {
|
|
213
|
-
if (!updated && currentConversation.value?.id === conversation.id && currentConversation.value.model === value) {
|
|
214
|
-
setConversationModel(previousModel);
|
|
215
|
-
} else if (updated && value) {
|
|
216
|
-
if (conversation.threadSessionId)
|
|
217
|
-
await agentWake.ensureReady(conversation.threadSessionId, value);
|
|
218
|
-
else
|
|
219
|
-
await agentWake.wake(void 0, value);
|
|
220
|
-
}
|
|
221
|
-
return updated;
|
|
222
|
-
});
|
|
223
|
-
modelUpdateInFlight.value = update.finally(() => {
|
|
224
|
-
if (modelUpdateInFlight.value === update)
|
|
225
|
-
modelUpdateInFlight.value = null;
|
|
226
|
-
});
|
|
227
|
-
}
|
|
246
|
+
if (conversation && conversation.model !== resolvedValue)
|
|
247
|
+
void persistConversationModel(conversation, resolvedValue, true);
|
|
228
248
|
}
|
|
229
249
|
});
|
|
230
250
|
const filesCount = computed(() => total.value);
|
|
@@ -479,11 +499,15 @@ async function handleSend(content, files, agentInputs) {
|
|
|
479
499
|
adoptConversation(grouped ? { ...conversation2, groupId } : conversation2);
|
|
480
500
|
updateConversationId(conversation2.id);
|
|
481
501
|
}
|
|
482
|
-
|
|
483
|
-
await modelUpdateInFlight.value;
|
|
502
|
+
await waitForPendingModelUpdate();
|
|
484
503
|
const conversation = currentConversation.value;
|
|
485
504
|
if (!conversation)
|
|
486
505
|
throw new Error("Erro ao preparar conversa");
|
|
506
|
+
await ensureConversationUsesSelectedModel(
|
|
507
|
+
conversation.model,
|
|
508
|
+
selectedModel.value,
|
|
509
|
+
(value) => persistConversationModel(conversation, value, false)
|
|
510
|
+
);
|
|
487
511
|
if (conversation.threadSessionId && resolvedFeatures.value.chatOutboundQueue) {
|
|
488
512
|
const wake = await agentWake.ensureReady(conversation.threadSessionId, selectedModel.value);
|
|
489
513
|
if (wake.status !== "ready") {
|
|
@@ -535,16 +559,25 @@ async function handleCancel() {
|
|
|
535
559
|
await cancelConversation();
|
|
536
560
|
}
|
|
537
561
|
async function handleRetry(messageId) {
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
562
|
+
await retryMessage(messageId, async () => {
|
|
563
|
+
await waitForPendingModelUpdate();
|
|
564
|
+
const conversation = currentConversation.value;
|
|
565
|
+
if (!conversation)
|
|
566
|
+
throw new Error("Erro ao preparar conversa");
|
|
567
|
+
await ensureConversationUsesSelectedModel(
|
|
568
|
+
conversation.model,
|
|
569
|
+
selectedModel.value,
|
|
570
|
+
(value) => persistConversationModel(conversation, value, false)
|
|
571
|
+
);
|
|
572
|
+
if (conversation.threadSessionId) {
|
|
573
|
+
const wake = await agentWake.ensureReady(conversation.threadSessionId, selectedModel.value);
|
|
574
|
+
if (wake.status !== "ready")
|
|
575
|
+
throw new Error("N\xE3o foi poss\xEDvel acordar o agente. Tente novamente.");
|
|
576
|
+
} else {
|
|
577
|
+
await agentWake.waitUntilSettled();
|
|
543
578
|
}
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
}
|
|
547
|
-
await retryMessage(messageId, claimableWakeSessionId());
|
|
579
|
+
return claimableWakeSessionId();
|
|
580
|
+
});
|
|
548
581
|
}
|
|
549
582
|
async function handleNewConversation(groupId) {
|
|
550
583
|
setPendingConversationGroup(groupId);
|
|
@@ -13,6 +13,7 @@ const props = defineProps({
|
|
|
13
13
|
initialConversationId: { type: [String, null], required: false },
|
|
14
14
|
conversationScope: { type: [String, null], required: false },
|
|
15
15
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
16
|
+
availableModels: { type: Array, required: false },
|
|
16
17
|
conversationCreatorFilter: { type: null, required: false },
|
|
17
18
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
18
19
|
hideSidebar: { type: Boolean, required: false },
|
|
@@ -53,6 +54,7 @@ provideEmbedConfig({
|
|
|
53
54
|
telaAgentId: normalizedTelaAgentId,
|
|
54
55
|
conversationScope: normalizedConversationScope,
|
|
55
56
|
defaultConversationCreatorFilter: computed(() => props.defaultConversationCreatorFilter),
|
|
57
|
+
availableModels: computed(() => props.availableModels),
|
|
56
58
|
conversationCreatorFilter: computed(() => props.conversationCreatorFilter),
|
|
57
59
|
telaAgentInputs: computed(() => props.telaAgentInputs),
|
|
58
60
|
workspaceSettings: computed(() => props.workspaceSettings),
|
|
@@ -3,7 +3,7 @@ import type { ChatActionPayload } from '../../messages/composables/chat-action.j
|
|
|
3
3
|
import type { MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import type { ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
5
|
import type { ChatFeatureConfig } from '../feature-config.js';
|
|
6
|
-
import type { ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
6
|
+
import type { AvailableChatModels, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
7
7
|
|
|
8
8
|
type MeistrariChatEmbedEmits = {
|
|
9
9
|
/** Fired when the active conversation changes. Pairs with `v-model:conversation-id`. */
|
|
@@ -54,4 +54,4 @@ type MeistrariChatEmbedSlots = SlotsType<{
|
|
|
54
54
|
declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
|
|
55
55
|
|
|
56
56
|
export default MeistrariChatEmbed;
|
|
57
|
-
export type { ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
57
|
+
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
@@ -6,6 +6,7 @@ const { hideSidebar = void 0, ...props } = defineProps({
|
|
|
6
6
|
initialConversationId: { type: [String, null], required: false },
|
|
7
7
|
conversationScope: { type: [String, null], required: false },
|
|
8
8
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
9
|
+
availableModels: { type: Array, required: false },
|
|
9
10
|
conversationCreatorFilter: { type: null, required: false },
|
|
10
11
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
11
12
|
hideSidebar: { type: Boolean, required: false },
|
|
@@ -62,6 +63,7 @@ const sharedEmbedProps = computed(() => ({
|
|
|
62
63
|
initialConversationId: props.initialConversationId,
|
|
63
64
|
conversationScope: props.conversationScope,
|
|
64
65
|
defaultConversationCreatorFilter: props.defaultConversationCreatorFilter,
|
|
66
|
+
availableModels: props.availableModels,
|
|
65
67
|
conversationCreatorFilter: props.conversationCreatorFilter,
|
|
66
68
|
hideConversationCreatorFilter: props.hideConversationCreatorFilter,
|
|
67
69
|
hideSettings: hideSettings.value,
|
|
@@ -3,7 +3,7 @@ import type { ChatActionPayload } from '../../messages/composables/chat-action.j
|
|
|
3
3
|
import type { MessageFeedbackPayload } from '../../messages/composables/chat-feedback.js';
|
|
4
4
|
import type { ChatMessageTerminalPayload } from '../../messages/composables/chat-message-terminal.js';
|
|
5
5
|
import type { ChatFeatureConfig } from '../feature-config.js';
|
|
6
|
-
import type { ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
6
|
+
import type { AvailableChatModels, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps } from '../types.js';
|
|
7
7
|
|
|
8
8
|
type MeistrariChatEmbedEmits = {
|
|
9
9
|
/** Fired when the active conversation changes. Pairs with `v-model:conversation-id`. */
|
|
@@ -54,4 +54,4 @@ type MeistrariChatEmbedSlots = SlotsType<{
|
|
|
54
54
|
declare const MeistrariChatEmbed: DefineSetupFnComponent<MeistrariChatEmbedProps, MeistrariChatEmbedEmits, MeistrariChatEmbedSlots>;
|
|
55
55
|
|
|
56
56
|
export default MeistrariChatEmbed;
|
|
57
|
-
export type { ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
57
|
+
export type { AvailableChatModels, ChatActionPayload, ChatEmbedVariant, ChatEmbedVariantProps, ChatFeatureConfig, ChatMessageTerminalPayload, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, MessageFeedbackPayload, TelaAgentChatEmbedProps };
|
|
@@ -5,6 +5,7 @@ import type { TelaAgentExecutionInput } from '../../types/schemas/integrations/t
|
|
|
5
5
|
import type { ChatLoadingMessageMode } from '../loading-messages.js';
|
|
6
6
|
import type { ChatCitationsConfig } from '../../citations/types.js';
|
|
7
7
|
import type { MessageFeedbackConfig, MessageFeedbackRating } from '../../messages/composables/chat-feedback.js';
|
|
8
|
+
import type { AvailableChatModels } from '../../messages/model-availability.js';
|
|
8
9
|
type ConfiguredTelaAgentInputs = DeepReadonly<TelaAgentExecutionInput[]> | null | undefined;
|
|
9
10
|
type ConfiguredMessageFeedback = Readonly<Record<string, MessageFeedbackRating>> | null | undefined;
|
|
10
11
|
export type EmbedConfig = {
|
|
@@ -12,6 +13,7 @@ export type EmbedConfig = {
|
|
|
12
13
|
telaAgentId: Ref<string | null>;
|
|
13
14
|
conversationScope: Ref<string | null>;
|
|
14
15
|
defaultConversationCreatorFilter: Ref<ConversationCreatorFilter>;
|
|
16
|
+
availableModels: Ref<AvailableChatModels | undefined>;
|
|
15
17
|
conversationCreatorFilter: Ref<ConversationCreatorFilter | undefined>;
|
|
16
18
|
telaAgentInputs: Ref<ConfiguredTelaAgentInputs>;
|
|
17
19
|
workspaceSettings: Ref<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
@@ -31,6 +33,7 @@ type EmbedConfigInput = {
|
|
|
31
33
|
telaAgentId?: MaybeRefOrGetter<string | null | undefined>;
|
|
32
34
|
conversationScope?: MaybeRefOrGetter<string | null | undefined>;
|
|
33
35
|
defaultConversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | null | undefined>;
|
|
36
|
+
availableModels?: MaybeRefOrGetter<AvailableChatModels | undefined>;
|
|
34
37
|
conversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | undefined>;
|
|
35
38
|
telaAgentInputs?: MaybeRefOrGetter<ConfiguredTelaAgentInputs>;
|
|
36
39
|
workspaceSettings?: MaybeRefOrGetter<DeepReadonly<WorkspaceSettings> | WorkspaceSettings | null | undefined>;
|
|
@@ -22,6 +22,7 @@ function useGlobalEmbedConfigState() {
|
|
|
22
22
|
telaAgentId: useState("chat-embed-config-tela-agent-id", () => null),
|
|
23
23
|
conversationScope: useState("chat-embed-config-conversation-scope", () => null),
|
|
24
24
|
defaultConversationCreatorFilter: useState("chat-embed-config-default-conversation-creator-filter", () => void 0),
|
|
25
|
+
availableModels: useState("chat-embed-config-available-models", () => void 0),
|
|
25
26
|
conversationCreatorFilter: useState("chat-embed-config-conversation-creator-filter", () => void 0),
|
|
26
27
|
telaAgentInputs: useState("chat-embed-config-tela-agent-inputs", () => void 0),
|
|
27
28
|
workspaceSettings: useState("chat-embed-config-workspace-settings", () => void 0),
|
|
@@ -43,6 +44,7 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
43
44
|
telaAgentId: computed(() => toValue(input.telaAgentId) ?? null),
|
|
44
45
|
conversationScope: computed(() => normalizeConversationScope(toValue(input.conversationScope))),
|
|
45
46
|
defaultConversationCreatorFilter: computed(() => toValue(input.defaultConversationCreatorFilter) ?? "all"),
|
|
47
|
+
availableModels: computed(() => toValue(input.availableModels)),
|
|
46
48
|
conversationCreatorFilter: computed(() => toValue(input.conversationCreatorFilter)),
|
|
47
49
|
telaAgentInputs: computed(() => toValue(input.telaAgentInputs)),
|
|
48
50
|
workspaceSettings: computed(() => toValue(input.workspaceSettings)),
|
|
@@ -65,6 +67,7 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
65
67
|
globalConfig.telaAgentId.value = config.telaAgentId.value;
|
|
66
68
|
globalConfig.conversationScope.value = config.conversationScope.value;
|
|
67
69
|
globalConfig.defaultConversationCreatorFilter.value = config.defaultConversationCreatorFilter.value;
|
|
70
|
+
globalConfig.availableModels.value = config.availableModels.value;
|
|
68
71
|
globalConfig.conversationCreatorFilter.value = config.conversationCreatorFilter.value;
|
|
69
72
|
globalConfig.telaAgentInputs.value = config.telaAgentInputs.value;
|
|
70
73
|
globalConfig.workspaceSettings.value = config.workspaceSettings.value;
|
|
@@ -94,6 +97,7 @@ export function useEmbedConfig() {
|
|
|
94
97
|
telaAgentId: computed(() => globalConfig.telaAgentId.value),
|
|
95
98
|
conversationScope: computed(() => globalConfig.conversationScope.value),
|
|
96
99
|
defaultConversationCreatorFilter: computed(() => globalConfig.defaultConversationCreatorFilter.value ?? "all"),
|
|
100
|
+
availableModels: computed(() => globalConfig.availableModels.value),
|
|
97
101
|
conversationCreatorFilter: computed(() => globalConfig.conversationCreatorFilter.value),
|
|
98
102
|
telaAgentInputs: computed(() => globalConfig.telaAgentInputs.value),
|
|
99
103
|
workspaceSettings: computed(() => globalConfig.workspaceSettings.value),
|
|
@@ -6,6 +6,8 @@ import type { ChatLoadingMessageMode } from './loading-messages.js';
|
|
|
6
6
|
import type { ChatFeatureConfig } from './feature-config.js';
|
|
7
7
|
import type { ChatCitationsConfig } from '../citations/types.js';
|
|
8
8
|
import type { MessageFeedbackConfig, MessageFeedbackRating } from '../messages/composables/chat-feedback.js';
|
|
9
|
+
import type { AvailableChatModels } from '../messages/model-availability.js';
|
|
10
|
+
export type { AvailableChatModels } from '../messages/model-availability.js';
|
|
9
11
|
export type ChatEmbedVariant = 'page' | 'floating' | 'sidepanel';
|
|
10
12
|
export type ChatSuggestion = {
|
|
11
13
|
/** Short label rendered on the suggestion pill. */
|
|
@@ -55,6 +57,12 @@ export type ChatEmbedSharedProps = {
|
|
|
55
57
|
* conversation in scope, `'mine'` shows only those created by the current user.
|
|
56
58
|
*/
|
|
57
59
|
defaultConversationCreatorFilter?: ConversationCreatorFilter;
|
|
60
|
+
/**
|
|
61
|
+
* Non-empty ordered list of models this embed may display and execute.
|
|
62
|
+
* When omitted, the full chat catalog remains available. The first model is
|
|
63
|
+
* used when a new or restored selection is not allowed by this list.
|
|
64
|
+
*/
|
|
65
|
+
availableModels?: AvailableChatModels;
|
|
58
66
|
/** Controlled creator filter. Use with `v-model:conversation-creator-filter` when the host changes it at runtime. */
|
|
59
67
|
conversationCreatorFilter?: ConversationCreatorFilter;
|
|
60
68
|
/** Hide the conversation creator filter while preserving its active value. */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<script setup>
|
|
2
2
|
import { chatModelOptions } from "../../types/schemas/chat/ui.js";
|
|
3
|
+
import { useEmbedConfig } from "../../embed/composables/embed-config";
|
|
4
|
+
import { resolveAvailableChatModels } from "../model-availability";
|
|
3
5
|
import TelaChatIconsAnthropic from "@meistrari/tela-build/components/tela/chat/icons/anthropic.vue";
|
|
4
6
|
import TelaChatIconsGemini from "@meistrari/tela-build/components/tela/chat/icons/gemini.vue";
|
|
5
7
|
import TelaChatIconsOpenai from "@meistrari/tela-build/components/tela/chat/icons/openai.vue";
|
|
@@ -7,23 +9,32 @@ defineProps({
|
|
|
7
9
|
disabled: { type: Boolean, required: false }
|
|
8
10
|
});
|
|
9
11
|
const model = defineModel({ type: [String, null], ...{ default: null } });
|
|
12
|
+
const embedConfig = useEmbedConfig();
|
|
10
13
|
const providerIcons = {
|
|
11
14
|
Anthropic: TelaChatIconsAnthropic,
|
|
12
15
|
OpenAI: TelaChatIconsOpenai,
|
|
13
16
|
Google: TelaChatIconsGemini
|
|
14
17
|
};
|
|
15
|
-
const options =
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
18
|
+
const options = computed(() => {
|
|
19
|
+
const availableModels = resolveAvailableChatModels(embedConfig?.availableModels.value);
|
|
20
|
+
return availableModels.map((model2) => {
|
|
21
|
+
const option = chatModelOptions.find((candidate) => candidate.value === model2);
|
|
22
|
+
if (!option)
|
|
23
|
+
throw new Error(`${model2} is missing from the chat model catalog`);
|
|
24
|
+
return {
|
|
25
|
+
value: option.value,
|
|
26
|
+
label: option.label,
|
|
27
|
+
description: option.description,
|
|
28
|
+
group: option.provider,
|
|
29
|
+
icon: providerIcons[option.provider],
|
|
30
|
+
cost: option.cost,
|
|
31
|
+
maxInputTokens: option.maxInputTokens,
|
|
32
|
+
maxOutputTokens: option.maxOutputTokens,
|
|
33
|
+
isMultiModal: option.isMultiModal,
|
|
34
|
+
tabs: [...option.tabs]
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
});
|
|
27
38
|
const tabLabels = {
|
|
28
39
|
all: "Todos",
|
|
29
40
|
advanced: "Avan\xE7ados",
|
|
@@ -40,7 +40,7 @@ export declare function useChat(options?: {
|
|
|
40
40
|
}>, queuedSend?: QueuedSend) => Promise<Message | null>;
|
|
41
41
|
flushOutboundQueue: (wakeSessionId?: string) => Promise<Message | null>;
|
|
42
42
|
failOutboundQueue: (message: string) => boolean;
|
|
43
|
-
retryMessage: (messageId: string,
|
|
43
|
+
retryMessage: (messageId: string, prepare?: () => Promise<string | undefined>) => Promise<boolean>;
|
|
44
44
|
cancelConversation: () => Promise<boolean>;
|
|
45
45
|
startPolling: () => void;
|
|
46
46
|
stopPolling: () => void;
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
CANCELLATION_FAILED_TEXT,
|
|
17
17
|
GENERATION_FAILED_TEXT
|
|
18
18
|
} from "../message-state.js";
|
|
19
|
+
import { useConversations } from "../../conversations/composables/conversations.js";
|
|
19
20
|
import { exportConversationToMarkdown } from "../../conversations/export.js";
|
|
20
21
|
import { resolveChatStateScope } from "../../conversations/scope.js";
|
|
21
22
|
import { getChatApiErrorCode, getChatApiErrorMessage, getChatApiErrorStatus } from "../../shared/chat-api-error.js";
|
|
@@ -45,6 +46,7 @@ export function useChat(options = {}) {
|
|
|
45
46
|
const embedConfig = useEmbedConfig();
|
|
46
47
|
const { user: authUser, activeOrganization } = useChatAuth();
|
|
47
48
|
const { addFilesToConversation } = useConversationFileActions();
|
|
49
|
+
const { updateConversationInList } = useConversations();
|
|
48
50
|
const chatScope = computed(() => resolveChatStateScope(
|
|
49
51
|
embedConfig?.workspaceId.value || activeOrganization.value?.id,
|
|
50
52
|
embedConfig?.telaAgentId.value,
|
|
@@ -118,9 +120,26 @@ export function useChat(options = {}) {
|
|
|
118
120
|
schedulePreparingStep(0);
|
|
119
121
|
}
|
|
120
122
|
const error = ref(null);
|
|
121
|
-
const
|
|
122
|
-
const
|
|
123
|
-
const
|
|
123
|
+
const titleGeneratedBuckets = useState("chat-title-generated", () => ({}));
|
|
124
|
+
const generatingTitleBuckets = useState("chat-generating-title", () => ({}));
|
|
125
|
+
const animatedTitleBuckets = useState("chat-animated-title", () => ({}));
|
|
126
|
+
const generatingTitle = computed(() => {
|
|
127
|
+
const conversationId = currentConversation.value?.id;
|
|
128
|
+
return conversationId ? generatingTitleBuckets.value[conversationId] ?? false : false;
|
|
129
|
+
});
|
|
130
|
+
const animatedTitle = computed(() => {
|
|
131
|
+
const conversationId = currentConversation.value?.id;
|
|
132
|
+
return conversationId ? animatedTitleBuckets.value[conversationId] ?? null : null;
|
|
133
|
+
});
|
|
134
|
+
function markTitleGenerated(conversationId, generated) {
|
|
135
|
+
titleGeneratedBuckets.value = { ...titleGeneratedBuckets.value, [conversationId]: generated };
|
|
136
|
+
}
|
|
137
|
+
function setGeneratingTitle(conversationId, generating) {
|
|
138
|
+
generatingTitleBuckets.value = { ...generatingTitleBuckets.value, [conversationId]: generating };
|
|
139
|
+
}
|
|
140
|
+
function setAnimatedTitle(conversationId, title) {
|
|
141
|
+
animatedTitleBuckets.value = { ...animatedTitleBuckets.value, [conversationId]: title };
|
|
142
|
+
}
|
|
124
143
|
const hasPendingMessage = computed(
|
|
125
144
|
() => messages.value.some((m) => m.status === "pending")
|
|
126
145
|
);
|
|
@@ -338,7 +357,6 @@ export function useChat(options = {}) {
|
|
|
338
357
|
};
|
|
339
358
|
const adoptConversation = (conv) => {
|
|
340
359
|
currentConversation.value = { ...conv, messages: messages.value };
|
|
341
|
-
titleGenerated.value = false;
|
|
342
360
|
};
|
|
343
361
|
const setConversation = (conv) => {
|
|
344
362
|
if (currentConversation.value && currentConversation.value.id !== conv.id) {
|
|
@@ -353,13 +371,11 @@ export function useChat(options = {}) {
|
|
|
353
371
|
agentSessionStatus.value = null;
|
|
354
372
|
agentSessionExecutable.value = false;
|
|
355
373
|
agentSessionRewakeable.value = false;
|
|
356
|
-
titleGenerated.value = false;
|
|
357
374
|
error.value = null;
|
|
358
375
|
};
|
|
359
376
|
const loadConversation = async (id) => {
|
|
360
377
|
loading.value = true;
|
|
361
378
|
error.value = null;
|
|
362
|
-
titleGenerated.value = false;
|
|
363
379
|
try {
|
|
364
380
|
const data = await $fetch(
|
|
365
381
|
chatApi.path(`/conversations/${id}`),
|
|
@@ -369,9 +385,8 @@ export function useChat(options = {}) {
|
|
|
369
385
|
messages.value = data.messages;
|
|
370
386
|
pendingStreamReconciliationIds.value = /* @__PURE__ */ new Set();
|
|
371
387
|
pendingRealResultIds.value = /* @__PURE__ */ new Set();
|
|
372
|
-
if (shouldTreatLoadedConversationTitleAsGenerated(data.messages))
|
|
373
|
-
|
|
374
|
-
}
|
|
388
|
+
if (shouldTreatLoadedConversationTitleAsGenerated(data.messages))
|
|
389
|
+
markTitleGenerated(data.id, true);
|
|
375
390
|
const pendingAssistant = data.messages.findLast((m) => m.role === "assistant" && m.status === "pending");
|
|
376
391
|
if (pendingAssistant) {
|
|
377
392
|
streamingMessageId.value = pendingAssistant.id;
|
|
@@ -713,19 +728,24 @@ export function useChat(options = {}) {
|
|
|
713
728
|
return false;
|
|
714
729
|
}
|
|
715
730
|
};
|
|
716
|
-
const retryMessage = async (messageId,
|
|
731
|
+
const retryMessage = async (messageId, prepare) => {
|
|
717
732
|
if (!currentConversation.value)
|
|
718
733
|
return false;
|
|
734
|
+
const conversationId = currentConversation.value.id;
|
|
719
735
|
error.value = null;
|
|
720
|
-
|
|
721
|
-
if (!retry)
|
|
722
|
-
return false;
|
|
723
|
-
messages.value = retry.messages;
|
|
724
|
-
streamingMessageId.value = messageId;
|
|
725
|
-
directStream.beginMessage();
|
|
736
|
+
let retry = null;
|
|
726
737
|
try {
|
|
738
|
+
const wakeSessionId = prepare ? await prepare() : void 0;
|
|
739
|
+
if (currentConversation.value?.id !== conversationId)
|
|
740
|
+
return false;
|
|
741
|
+
retry = beginAssistantMessageRetry(messages.value, messageId);
|
|
742
|
+
if (!retry)
|
|
743
|
+
return false;
|
|
744
|
+
messages.value = retry.messages;
|
|
745
|
+
streamingMessageId.value = messageId;
|
|
746
|
+
directStream.beginMessage();
|
|
727
747
|
await $fetch(
|
|
728
|
-
chatApi.path(`/conversations/${
|
|
748
|
+
chatApi.path(`/conversations/${conversationId}/messages/${messageId}/retry`),
|
|
729
749
|
chatApi.withChatHeaders({
|
|
730
750
|
method: "POST",
|
|
731
751
|
body: wakeSessionId ? { wakeSessionId } : {}
|
|
@@ -734,39 +754,46 @@ export function useChat(options = {}) {
|
|
|
734
754
|
startPolling();
|
|
735
755
|
return true;
|
|
736
756
|
} catch (err) {
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
757
|
+
if (retry) {
|
|
758
|
+
messages.value = restoreAssistantMessageAfterRetryFailure(messages.value, retry.originalMessage);
|
|
759
|
+
streamingMessageId.value = null;
|
|
760
|
+
directStream.disconnect();
|
|
761
|
+
}
|
|
740
762
|
const errorMessage = getChatApiErrorCode(err) === "workspace_agent_not_ready" ? WORKSPACE_AGENT_NOT_READY_TEXT : err instanceof Error ? err.message : "Erro ao reenviar mensagem";
|
|
741
763
|
error.value = errorMessage;
|
|
742
764
|
Sentry.captureException(err);
|
|
743
765
|
return false;
|
|
744
766
|
}
|
|
745
767
|
};
|
|
746
|
-
const animateTitle = (title) => {
|
|
768
|
+
const animateTitle = (title, conversationId) => {
|
|
747
769
|
return new Promise((resolve) => {
|
|
748
|
-
|
|
770
|
+
setAnimatedTitle(conversationId, "");
|
|
749
771
|
let index = 0;
|
|
750
772
|
const interval = setInterval(() => {
|
|
751
|
-
if (
|
|
752
|
-
|
|
773
|
+
if (currentConversation.value?.id !== conversationId) {
|
|
774
|
+
clearInterval(interval);
|
|
775
|
+
setAnimatedTitle(conversationId, null);
|
|
776
|
+
resolve(false);
|
|
777
|
+
} else if (index < title.length) {
|
|
778
|
+
setAnimatedTitle(conversationId, title.slice(0, index + 1));
|
|
753
779
|
index++;
|
|
754
780
|
} else {
|
|
755
781
|
clearInterval(interval);
|
|
756
|
-
|
|
757
|
-
resolve();
|
|
782
|
+
setAnimatedTitle(conversationId, null);
|
|
783
|
+
resolve(true);
|
|
758
784
|
}
|
|
759
785
|
}, 30);
|
|
760
786
|
});
|
|
761
787
|
};
|
|
762
788
|
const generateTitle = async () => {
|
|
763
|
-
|
|
789
|
+
const conversation = currentConversation.value;
|
|
790
|
+
if (!conversation || titleGeneratedBuckets.value[conversation.id])
|
|
764
791
|
return;
|
|
765
792
|
const titleMessages = selectTitleGenerationMessages(messages.value);
|
|
766
793
|
if (!titleMessages)
|
|
767
794
|
return;
|
|
768
|
-
|
|
769
|
-
|
|
795
|
+
markTitleGenerated(conversation.id, true);
|
|
796
|
+
setGeneratingTitle(conversation.id, true);
|
|
770
797
|
try {
|
|
771
798
|
const { title } = await $fetch(
|
|
772
799
|
chatApi.path("/conversations/generate-title"),
|
|
@@ -778,24 +805,27 @@ export function useChat(options = {}) {
|
|
|
778
805
|
}
|
|
779
806
|
})
|
|
780
807
|
);
|
|
781
|
-
if (title
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
}
|
|
788
|
-
})
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
808
|
+
if (!title)
|
|
809
|
+
return;
|
|
810
|
+
const updated = await $fetch(
|
|
811
|
+
chatApi.path(`/conversations/${conversation.id}`),
|
|
812
|
+
chatApi.withChatHeaders({
|
|
813
|
+
method: "PATCH",
|
|
814
|
+
body: { title }
|
|
815
|
+
})
|
|
816
|
+
);
|
|
817
|
+
updateConversationInList(updated);
|
|
818
|
+
if (currentConversation.value?.id === conversation.id && await animateTitle(title, conversation.id)) {
|
|
819
|
+
const current = currentConversation.value;
|
|
820
|
+
if (current?.id === conversation.id)
|
|
821
|
+
currentConversation.value = { ...current, title };
|
|
793
822
|
}
|
|
794
823
|
} catch (err) {
|
|
824
|
+
markTitleGenerated(conversation.id, false);
|
|
795
825
|
Sentry.captureException(err);
|
|
796
826
|
} finally {
|
|
797
|
-
|
|
798
|
-
|
|
827
|
+
setGeneratingTitle(conversation.id, false);
|
|
828
|
+
setAnimatedTitle(conversation.id, null);
|
|
799
829
|
}
|
|
800
830
|
};
|
|
801
831
|
const exportToMarkdown = () => {
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ChatModel } from '../types/schemas/chat/models.js';
|
|
2
|
+
export type AvailableChatModels = readonly [ChatModel, ...ChatModel[]];
|
|
3
|
+
export declare const MODEL_UPDATE_FAILED_MESSAGE = "N\u00E3o foi poss\u00EDvel atualizar o modelo da conversa";
|
|
4
|
+
export declare function resolveAvailableChatModels(availableModels?: readonly ChatModel[]): readonly ChatModel[];
|
|
5
|
+
export declare function resolveChatModelSelection(selectedModel: string | null, availableModels?: readonly ChatModel[]): string | null;
|
|
6
|
+
export declare function ensureConversationUsesSelectedModel(conversationModel: string | null, selectedModel: string | null, updateModel: (model: string | null) => Promise<boolean>): Promise<void>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { chatModelIds, isValidChatModel } from "../types/schemas/chat/models.js";
|
|
2
|
+
export const MODEL_UPDATE_FAILED_MESSAGE = "N\xE3o foi poss\xEDvel atualizar o modelo da conversa";
|
|
3
|
+
export function resolveAvailableChatModels(availableModels) {
|
|
4
|
+
if (availableModels === void 0)
|
|
5
|
+
return chatModelIds;
|
|
6
|
+
if (availableModels.length === 0)
|
|
7
|
+
throw new Error("availableModels must contain at least one model");
|
|
8
|
+
const uniqueModels = [];
|
|
9
|
+
for (const model of availableModels) {
|
|
10
|
+
if (!isValidChatModel(model))
|
|
11
|
+
throw new Error(`${model} is not a supported chat model`);
|
|
12
|
+
if (!uniqueModels.includes(model))
|
|
13
|
+
uniqueModels.push(model);
|
|
14
|
+
}
|
|
15
|
+
return uniqueModels;
|
|
16
|
+
}
|
|
17
|
+
export function resolveChatModelSelection(selectedModel, availableModels) {
|
|
18
|
+
if (availableModels === void 0)
|
|
19
|
+
return selectedModel;
|
|
20
|
+
const resolvedModels = resolveAvailableChatModels(availableModels);
|
|
21
|
+
return selectedModel && resolvedModels.includes(selectedModel) ? selectedModel : resolvedModels[0];
|
|
22
|
+
}
|
|
23
|
+
export async function ensureConversationUsesSelectedModel(conversationModel, selectedModel, updateModel) {
|
|
24
|
+
if (conversationModel === selectedModel)
|
|
25
|
+
return;
|
|
26
|
+
if (!await updateModel(selectedModel))
|
|
27
|
+
throw new Error(MODEL_UPDATE_FAILED_MESSAGE);
|
|
28
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { defineEventHandler, getRouterParam } from "h3";
|
|
2
|
+
import { prefixProxyPath, proxyChatApiRequest } from "../../../../utils/chat-api-proxy.js";
|
|
3
|
+
export default defineEventHandler((event) => {
|
|
4
|
+
const groupId = getRouterParam(event, "groupId") || "";
|
|
5
|
+
return proxyChatApiRequest(event, prefixProxyPath("conversations/groups", groupId));
|
|
6
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { ChatCitationsConfig, CitationMeta, CitationRef, } from '../citations/types.js';
|
|
2
2
|
export type { ChatFeatureConfig } from '../embed/feature-config.js';
|
|
3
|
-
export type { ChatActor, ChatEmbedSharedProps, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps, } from '../embed/types.js';
|
|
3
|
+
export type { AvailableChatModels, ChatActor, ChatEmbedSharedProps, ChatEmbedVariant, ChatEmbedVariantProps, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps, } from '../embed/types.js';
|
|
4
4
|
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';
|
|
@@ -216,6 +216,7 @@ export declare const createConversationRequestSchema: z.ZodObject<{
|
|
|
216
216
|
"claude-opus-5": "claude-opus-5";
|
|
217
217
|
"claude-opus-4-8": "claude-opus-4-8";
|
|
218
218
|
"claude-sonnet-5": "claude-sonnet-5";
|
|
219
|
+
"claude-sonnet-4-6": "claude-sonnet-4-6";
|
|
219
220
|
"claude-haiku-4-5": "claude-haiku-4-5";
|
|
220
221
|
}>>>;
|
|
221
222
|
agentInputs: z.ZodOptional<z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -253,6 +254,7 @@ export declare const updateConversationRequestSchema: z.ZodObject<{
|
|
|
253
254
|
"claude-opus-5": "claude-opus-5";
|
|
254
255
|
"claude-opus-4-8": "claude-opus-4-8";
|
|
255
256
|
"claude-sonnet-5": "claude-sonnet-5";
|
|
257
|
+
"claude-sonnet-4-6": "claude-sonnet-4-6";
|
|
256
258
|
"claude-haiku-4-5": "claude-haiku-4-5";
|
|
257
259
|
}>>>;
|
|
258
260
|
}, z.core.$strict>;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
export declare const chatModelIds: readonly ["claude-opus-5", "claude-opus-4-8", "claude-sonnet-5", "claude-haiku-4-5"];
|
|
2
|
+
export declare const chatModelIds: readonly ["claude-opus-5", "claude-opus-4-8", "claude-sonnet-5", "claude-sonnet-4-6", "claude-haiku-4-5"];
|
|
3
3
|
export declare const chatModelSchema: z.ZodEnum<{
|
|
4
4
|
"claude-opus-5": "claude-opus-5";
|
|
5
5
|
"claude-opus-4-8": "claude-opus-4-8";
|
|
6
6
|
"claude-sonnet-5": "claude-sonnet-5";
|
|
7
|
+
"claude-sonnet-4-6": "claude-sonnet-4-6";
|
|
7
8
|
"claude-haiku-4-5": "claude-haiku-4-5";
|
|
8
9
|
}>;
|
|
9
10
|
export type ChatModel = z.infer<typeof chatModelSchema>;
|
|
@@ -49,6 +49,16 @@ export declare const chatModelOptions: readonly [{
|
|
|
49
49
|
readonly maxOutputTokens: 64000;
|
|
50
50
|
readonly isMultiModal: true;
|
|
51
51
|
readonly tabs: readonly ["all", "advanced", "multimodal"];
|
|
52
|
+
}, {
|
|
53
|
+
readonly value: "claude-sonnet-4-6";
|
|
54
|
+
readonly label: "Claude 4.6 Sonnet";
|
|
55
|
+
readonly description: "Agente rápido para tarefas avançadas";
|
|
56
|
+
readonly provider: "Anthropic";
|
|
57
|
+
readonly cost: 4;
|
|
58
|
+
readonly maxInputTokens: 1000000;
|
|
59
|
+
readonly maxOutputTokens: 64000;
|
|
60
|
+
readonly isMultiModal: true;
|
|
61
|
+
readonly tabs: readonly ["all", "advanced", "multimodal"];
|
|
52
62
|
}, {
|
|
53
63
|
readonly value: "claude-haiku-4-5";
|
|
54
64
|
readonly label: "Claude 4.5 Haiku";
|
|
@@ -9,6 +9,7 @@ export const chatModelOptions = [
|
|
|
9
9
|
{ value: 'claude-opus-5', label: 'Claude Opus 5', description: 'Agente de ponta para trabalho complexo', provider: 'Anthropic', cost: 5, maxInputTokens: 1_000_000, maxOutputTokens: 128_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
|
|
10
10
|
{ value: 'claude-opus-4-8', label: 'Claude 4.8 Opus', description: 'Agente de ponta para tarefas complexas', provider: 'Anthropic', cost: 4, maxInputTokens: 1_000_000, maxOutputTokens: 128_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
|
|
11
11
|
{ value: 'claude-sonnet-5', label: 'Claude Sonnet 5', description: 'Agente rápido para tarefas avançadas', provider: 'Anthropic', cost: 4, maxInputTokens: 1_000_000, maxOutputTokens: 64_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
|
|
12
|
+
{ value: 'claude-sonnet-4-6', label: 'Claude 4.6 Sonnet', description: 'Agente rápido para tarefas avançadas', provider: 'Anthropic', cost: 4, maxInputTokens: 1_000_000, maxOutputTokens: 64_000, isMultiModal: true, tabs: ['all', 'advanced', 'multimodal'] },
|
|
12
13
|
{ value: 'claude-haiku-4-5', label: 'Claude 4.5 Haiku', description: 'Agente rápido para tarefas simples', provider: 'Anthropic', cost: 3, maxInputTokens: 200_000, maxOutputTokens: 64_000, isMultiModal: true, tabs: ['all', 'cheap', 'multimodal'] },
|
|
13
14
|
];
|
|
14
15
|
export const topbarTabs = ['chat', 'files', 'usage'];
|
|
@@ -278,6 +278,7 @@ export declare const telaAgentWakeRequestSchema: z.ZodObject<{
|
|
|
278
278
|
"claude-opus-5": "claude-opus-5";
|
|
279
279
|
"claude-opus-4-8": "claude-opus-4-8";
|
|
280
280
|
"claude-sonnet-5": "claude-sonnet-5";
|
|
281
|
+
"claude-sonnet-4-6": "claude-sonnet-4-6";
|
|
281
282
|
"claude-haiku-4-5": "claude-haiku-4-5";
|
|
282
283
|
}>>;
|
|
283
284
|
}, z.core.$strip>;
|
package/dist/types.d.mts
CHANGED
|
@@ -6,7 +6,7 @@ export type ModuleOptions = typeof Module extends NuxtModule<infer O> ? Partial<
|
|
|
6
6
|
|
|
7
7
|
export { ChatMessageStatus } from '../dist/runtime/messages/composables/chat-message-terminal.js'
|
|
8
8
|
|
|
9
|
-
export { type ChatActionPayload, type ChatActor, type ChatEmbedSharedProps, type ChatEmbedVariant, type ChatEmbedVariantProps, type ChatFeatureConfig, type ChatMessageTerminalPayload, type ChatSidebarConfig, type ChatSuggestion, type DefaultChatEmbedProps, type MeistrariChatEmbedProps, type MessageFeedbackConfig, type MessageFeedbackPayload, type MessageFeedbackRating, type MessageFeedbackSubmitHandler, type MessageFeedbackSubmitResult, type MessageOverviewResponse, type TelaAgentChatEmbedProps, type TelaAgentExecutionInput } from '../dist/runtime/types/embed.js'
|
|
9
|
+
export { type AvailableChatModels, type ChatActionPayload, type ChatActor, type ChatEmbedSharedProps, type ChatEmbedVariant, type ChatEmbedVariantProps, type ChatFeatureConfig, type ChatMessageTerminalPayload, type ChatSidebarConfig, type ChatSuggestion, type DefaultChatEmbedProps, type MeistrariChatEmbedProps, type MessageFeedbackConfig, type MessageFeedbackPayload, type MessageFeedbackRating, type MessageFeedbackSubmitHandler, type MessageFeedbackSubmitResult, type MessageOverviewResponse, type TelaAgentChatEmbedProps, type TelaAgentExecutionInput } from '../dist/runtime/types/embed.js'
|
|
10
10
|
|
|
11
11
|
export { default } from './module.mjs'
|
|
12
12
|
|