@meistrari/chat-nuxt 4.7.0 → 4.8.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -1
- package/dist/module.json +1 -1
- package/dist/runtime/conversations/composables/conversations.d.ts +2 -0
- package/dist/runtime/conversations/composables/conversations.js +2 -0
- package/dist/runtime/embed/components/chat-embed-inner.d.vue.ts +10 -10
- package/dist/runtime/embed/components/chat-embed-inner.vue +43 -1
- package/dist/runtime/embed/components/chat-embed-inner.vue.d.ts +10 -10
- package/dist/runtime/embed/components/chat-embed.vue +2 -0
- package/dist/runtime/embed/components/meistrari-chat-embed.vue +2 -0
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +7 -3
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue +4 -1
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +7 -3
- 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/execution-controls.d.ts +26 -0
- package/dist/runtime/embed/execution-controls.js +18 -0
- package/dist/runtime/embed/feature-config.d.ts +4 -1
- package/dist/runtime/embed/feature-config.js +5 -3
- package/dist/runtime/embed/types.d.ts +3 -0
- package/dist/runtime/lightweight/messages/composables/chat.d.ts +4 -0
- package/dist/runtime/messages/components/chat-execution-mode-selector.d.vue.ts +17 -0
- package/dist/runtime/messages/components/chat-execution-mode-selector.vue +40 -0
- package/dist/runtime/messages/components/chat-execution-mode-selector.vue.d.ts +17 -0
- package/dist/runtime/messages/components/chat-message-input.d.vue.ts +4 -0
- package/dist/runtime/messages/components/chat-message-input.vue +21 -1
- package/dist/runtime/messages/components/chat-message-input.vue.d.ts +4 -0
- package/dist/runtime/messages/composables/chat.d.ts +5 -0
- package/dist/runtime/messages/composables/chat.js +27 -1
- package/dist/runtime/types/embed.d.ts +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -101,6 +101,7 @@ Declared in `src/runtime/embed/types.ts`; prop, feature-flag, and event payload
|
|
|
101
101
|
| `defaultConversationCreatorFilter` | `'all' \| 'mine'` | `'all'` | Initial sidebar creator filter: every conversation in scope, or only the current user's |
|
|
102
102
|
| `availableModels` | `AvailableChatModels` | Harness catalog | Visual filter and ordering for catalog options. Unknown ids are omitted; if no ids match, the full catalog is shown. Does not change defaults, restored selections or execution. The Agent validates availability |
|
|
103
103
|
| `defaultModel` | `ChatModel` | Package default | Initial model for untouched drafts. Explicit selections and existing conversations take precedence; `availableModels` only filters the selector |
|
|
104
|
+
| `executionControls` | `ChatExecutionControls` | Legacy feature flags | Choose `hidden`, `simple` (Padrão / Aprofundar), or `advanced` (model and effort pickers). See below |
|
|
104
105
|
| `defaultReasoningEffort` | `ChatReasoningEffort` | Automatic (`null`) | Initial reasoning effort for untouched drafts. Explicit user choices (including automatic) take precedence |
|
|
105
106
|
| `conversationCreatorFilter` | `'all' \| 'mine'` | — | Controlled sidebar creator filter; use with `v-model:conversation-creator-filter` when the host changes it at runtime |
|
|
106
107
|
| `hideConversationCreatorFilter` | `boolean` | `false` | Hide the creator selector without changing the active filter |
|
|
@@ -109,7 +110,7 @@ Declared in `src/runtime/embed/types.ts`; prop, feature-flag, and event payload
|
|
|
109
110
|
| `telaAgentInputs` | `TelaAgentExecutionInput[] \| null` | `undefined` | Inputs sent with each Tela agent run; hides the variables panel when non-null |
|
|
110
111
|
| `workspaceSettings` | `WorkspaceSettings \| null` | `null` | Override settings from host app; not accepted in Tela agent mode |
|
|
111
112
|
| `user` | `ChatActor \| null` | `null` | Override current user display info; not accepted in Tela agent mode |
|
|
112
|
-
| `features` | `Partial<ChatFeatureConfig>` | `{}` | Toggle `showUsageTab`, `showDebugOption`, `showCancelButton`, `showTtft`, `chatOutboundQueue`, `showPromptInputHints`, `showModelSelector`, and `showReasoningEffortSelector`; all released features default to `true` |
|
|
113
|
+
| `features` | `Partial<ChatFeatureConfig>` | `{}` | Toggle `showUsageTab`, `showDebugOption`, `showCancelButton`, `showTtft`, `chatOutboundQueue`, `showPromptInputHints`, `showModelSelector`, and `showReasoningEffortSelector`; all released features default to `true`. The two picker flags are deprecated in favor of `executionControls` |
|
|
113
114
|
| `loadingMessages` | `readonly string[] \| null` | Default chat messages | Override pending-response messages |
|
|
114
115
|
| `loadingMessagesMode` | `'ordered' \| 'random' \| null` | `'ordered'` | Rotate custom messages in order or at random; only applies when `loadingMessages` has a non-empty message |
|
|
115
116
|
| `labels` | `Partial<ChatLabels>` | Portuguese defaults | Override conversation-search text; see [UI labels](docs/guides/embedding.md#ui-labels) for supported keys and surfaces |
|
|
@@ -181,3 +182,59 @@ Peer dependencies:
|
|
|
181
182
|
|---------|---------|---------|
|
|
182
183
|
| `nuxt` | `^3.17.0 \|\| ^4.0.0` | Host framework |
|
|
183
184
|
| `vue` | `^3.5.0` | Host Vue runtime |
|
|
185
|
+
|
|
186
|
+
### Execution controls
|
|
187
|
+
|
|
188
|
+
`executionControls` selects how users configure a response. Omit it to preserve
|
|
189
|
+
existing behavior, including `features.showModelSelector` and
|
|
190
|
+
`features.showReasoningEffortSelector`. Both legacy fields remain supported and
|
|
191
|
+
are marked `@deprecated` for editor guidance. When `executionControls` is present,
|
|
192
|
+
it takes precedence over both legacy flags as a whole.
|
|
193
|
+
|
|
194
|
+
```vue
|
|
195
|
+
<MeistrariChatEmbed
|
|
196
|
+
:execution-controls="{
|
|
197
|
+
mode: 'simple',
|
|
198
|
+
profiles: {
|
|
199
|
+
default: { model: standardModelId, reasoningEffort: 'medium' },
|
|
200
|
+
deep: { model: deepModelId, reasoningEffort: 'high' },
|
|
201
|
+
},
|
|
202
|
+
}"
|
|
203
|
+
/>
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Supply model IDs available to the configured agent and effort levels supported
|
|
207
|
+
by those models. Both profiles may use the same model. An explicit `null` effort
|
|
208
|
+
uses the agent's configured effort. Profile selection sends model and effort in
|
|
209
|
+
one update; a failed update restores both values. Sending waits for that update.
|
|
210
|
+
|
|
211
|
+
In `simple` mode, new conversations start with the `default` profile, regardless
|
|
212
|
+
of `defaultModel` and `defaultReasoningEffort`. A selection stays within the current
|
|
213
|
+
conversation. Changing control modes preserves explicit draft choices. Starting
|
|
214
|
+
a new conversation discards a simple selection even if the controls have since
|
|
215
|
+
been hidden or switched to advanced mode. If only one field is manually changed in advanced mode, the remaining simple
|
|
216
|
+
selection still causes both fields to reset for a new conversation. Manually
|
|
217
|
+
replacing both fields in advanced mode retains the existing behavior of carrying
|
|
218
|
+
them over to new conversations.
|
|
219
|
+
Restored conversations keep their settings: the control shows
|
|
220
|
+
**Personalizado** when the saved model and effort do not match either profile.
|
|
221
|
+
The menu still offers only **Padrão** and **Aprofundar**. Changes apply to subsequent
|
|
222
|
+
messages and do not regenerate earlier responses. If profiles are identical,
|
|
223
|
+
**Padrão** wins the label match.
|
|
224
|
+
|
|
225
|
+
In `hidden` and `advanced` modes, the existing model and effort defaults and saved
|
|
226
|
+
conversation settings retain their behavior. Hiding controls does not force a
|
|
227
|
+
model or effort. `availableModels` continues to filter the advanced model picker;
|
|
228
|
+
it does not filter or rewrite the simple profiles.
|
|
229
|
+
|
|
230
|
+
| Legacy configuration | Replacement |
|
|
231
|
+
| --- | --- |
|
|
232
|
+
| Both picker flags `false` | `{ mode: 'hidden' }` |
|
|
233
|
+
| Both picker flags `true` | `{ mode: 'advanced' }` |
|
|
234
|
+
| Only effort picker `false` | `{ mode: 'advanced', showReasoningEffortSelector: false }` |
|
|
235
|
+
| Only model picker `false` | `{ mode: 'advanced', showModelSelector: false }` |
|
|
236
|
+
|
|
237
|
+
Advanced picker flags default to `true`. Import `ChatExecutionControls` and
|
|
238
|
+
`ChatExecutionProfile` from `@meistrari/chat-nuxt/types/embed` when declaring host
|
|
239
|
+
configuration separately. `defaultModel` and `defaultReasoningEffort` are not
|
|
240
|
+
deprecated.
|
package/dist/module.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
1
2
|
import type { DeepReadonly } from 'vue';
|
|
2
3
|
import type { Conversation, ConversationWithMessages, CreateConversationRequest } from '../../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
@@ -14,6 +15,7 @@ export declare function useConversations(): {
|
|
|
14
15
|
renameConversation: (id: string, title: string) => Promise<boolean>;
|
|
15
16
|
updateConversationModel: (id: string, model: string | null) => Promise<boolean>;
|
|
16
17
|
updateConversationReasoningEffort: (id: string, reasoningEffort: ChatReasoningEffort | null) => Promise<boolean>;
|
|
18
|
+
updateConversationExecutionProfile: (id: string, profile: ChatExecutionProfile) => Promise<boolean>;
|
|
17
19
|
moveConversationToGroup: (id: string, groupId: string | null) => Promise<boolean>;
|
|
18
20
|
duplicateConversation: (id: string) => Promise<ConversationWithMessages | null>;
|
|
19
21
|
forkConversation: (id: string, messageId: string) => Promise<ConversationWithMessages | null>;
|
|
@@ -505,6 +505,7 @@ export function useConversations() {
|
|
|
505
505
|
};
|
|
506
506
|
const updateConversationModel = (id, model) => patchConversationSetting(id, { model }, "Erro ao atualizar modelo da conversa");
|
|
507
507
|
const updateConversationReasoningEffort = (id, reasoningEffort) => patchConversationSetting(id, { reasoningEffort }, "Erro ao atualizar o esfor\xE7o de racioc\xEDnio da conversa");
|
|
508
|
+
const updateConversationExecutionProfile = (id, profile) => patchConversationSetting(id, profile, "Erro ao atualizar o modo de resposta da conversa");
|
|
508
509
|
const forkConversation = async (id, messageId) => {
|
|
509
510
|
error.value = null;
|
|
510
511
|
const statusToast = useStatusToast();
|
|
@@ -561,6 +562,7 @@ export function useConversations() {
|
|
|
561
562
|
renameConversation,
|
|
562
563
|
updateConversationModel,
|
|
563
564
|
updateConversationReasoningEffort,
|
|
565
|
+
updateConversationExecutionProfile,
|
|
564
566
|
moveConversationToGroup,
|
|
565
567
|
duplicateConversation,
|
|
566
568
|
forkConversation,
|
|
@@ -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_92: {}, __VLS_105: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_118: {}, __VLS_127: {}, __VLS_191: {}, __VLS_210: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_223: {};
|
|
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_92) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_105) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_118) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_127) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'composer-bottom'?: (props: typeof
|
|
38
|
+
'composer-bottom'?: (props: typeof __VLS_191) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'failed-message-actions'?: (props: typeof
|
|
40
|
+
'failed-message-actions'?: (props: typeof __VLS_210) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'composer-bottom'?: (props: typeof
|
|
42
|
+
'composer-bottom'?: (props: typeof __VLS_223) => 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;
|
|
@@ -97,6 +97,7 @@ const {
|
|
|
97
97
|
renameConversation,
|
|
98
98
|
updateConversationModel,
|
|
99
99
|
updateConversationReasoningEffort,
|
|
100
|
+
updateConversationExecutionProfile,
|
|
100
101
|
duplicateConversation,
|
|
101
102
|
forkConversation,
|
|
102
103
|
moveConversationToGroup,
|
|
@@ -173,7 +174,7 @@ const {
|
|
|
173
174
|
setPendingConversationGroup,
|
|
174
175
|
clearPendingConversationGroup
|
|
175
176
|
} = usePendingConversationGroup();
|
|
176
|
-
const resolvedFeatures = computed(() => resolveChatFeatures(props.features));
|
|
177
|
+
const resolvedFeatures = computed(() => resolveChatFeatures(props.features, embedConfig?.executionControls?.value));
|
|
177
178
|
const dropZoneRef = ref(null);
|
|
178
179
|
const activeTab = ref("chat");
|
|
179
180
|
const answerTarget = ref(null);
|
|
@@ -229,6 +230,7 @@ const {
|
|
|
229
230
|
setConversationModel,
|
|
230
231
|
pendingModelSelection,
|
|
231
232
|
setConversationReasoningEffort,
|
|
233
|
+
setConversationExecutionProfile,
|
|
232
234
|
pendingReasoningEffortSelection,
|
|
233
235
|
sendMessage,
|
|
234
236
|
flushOutboundQueue,
|
|
@@ -328,6 +330,32 @@ const selectedReasoningEffort = computed({
|
|
|
328
330
|
void persistConversationReasoningEffort(conversation, value);
|
|
329
331
|
}
|
|
330
332
|
});
|
|
333
|
+
function selectExecutionProfile(profile) {
|
|
334
|
+
if (modelUpdateInFlight.value || reasoningEffortUpdateInFlight.value)
|
|
335
|
+
return;
|
|
336
|
+
const conversation = currentConversation.value;
|
|
337
|
+
if (!conversation) {
|
|
338
|
+
pendingModelSelection.value = profile.model;
|
|
339
|
+
pendingReasoningEffortSelection.value = profile.reasoningEffort;
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
const previous = { model: conversation.model, reasoningEffort: conversation.reasoningEffort ?? null };
|
|
343
|
+
setConversationExecutionProfile(profile);
|
|
344
|
+
const update = updateConversationExecutionProfile(conversation.id, profile).then((updated) => {
|
|
345
|
+
if (!updated) {
|
|
346
|
+
if (currentConversation.value?.id === conversation.id && currentConversation.value.model === profile.model && (currentConversation.value.reasoningEffort ?? null) === profile.reasoningEffort) {
|
|
347
|
+
setConversationExecutionProfile(previous);
|
|
348
|
+
}
|
|
349
|
+
statusToast.update({ text: "N\xE3o foi poss\xEDvel atualizar o modo de resposta da conversa", icon: "i-ph-warning" });
|
|
350
|
+
}
|
|
351
|
+
return updated;
|
|
352
|
+
});
|
|
353
|
+
const trackedUpdate = update.finally(() => {
|
|
354
|
+
if (modelUpdateInFlight.value === trackedUpdate)
|
|
355
|
+
modelUpdateInFlight.value = null;
|
|
356
|
+
});
|
|
357
|
+
modelUpdateInFlight.value = trackedUpdate;
|
|
358
|
+
}
|
|
331
359
|
const filesCount = computed(() => total.value);
|
|
332
360
|
const showDetailsPanel = computed(() => !!currentConversation.value && !isMobile.value && !props.compact);
|
|
333
361
|
const detailsConversationId = computed(() => activeConversationId.value ?? currentConversation.value?.id ?? null);
|
|
@@ -1005,6 +1033,7 @@ async function handleDelete() {
|
|
|
1005
1033
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1006
1034
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1007
1035
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1036
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1008
1037
|
:show-debug-option="resolvedFeatures.showDebugOption"
|
|
1009
1038
|
:show-outdated-badge="showOutdatedBadge"
|
|
1010
1039
|
:show-outdated-banner="showOutdatedBanner"
|
|
@@ -1012,6 +1041,7 @@ async function handleDelete() {
|
|
|
1012
1041
|
:workspace-logo="workspaceLogo"
|
|
1013
1042
|
:workspace-name="workspaceName"
|
|
1014
1043
|
:workspace-settings="effectiveWorkspaceSettings"
|
|
1044
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1015
1045
|
@cancel="handleCancel"
|
|
1016
1046
|
@cancel-editing="cancelEditing"
|
|
1017
1047
|
@copy-link="handleShare()"
|
|
@@ -1048,6 +1078,8 @@ async function handleDelete() {
|
|
|
1048
1078
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1049
1079
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1050
1080
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1081
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1082
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1051
1083
|
/>
|
|
1052
1084
|
</template>
|
|
1053
1085
|
|
|
@@ -1093,7 +1125,9 @@ async function handleDelete() {
|
|
|
1093
1125
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1094
1126
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1095
1127
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1128
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1096
1129
|
centered
|
|
1130
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1097
1131
|
@send="handleSend"
|
|
1098
1132
|
@cancel="handleCancel"
|
|
1099
1133
|
/>
|
|
@@ -1147,7 +1181,9 @@ async function handleDelete() {
|
|
|
1147
1181
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1148
1182
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1149
1183
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1184
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1150
1185
|
has-disclaimer
|
|
1186
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1151
1187
|
@send="handleSend"
|
|
1152
1188
|
@cancel="handleCancel"
|
|
1153
1189
|
/>
|
|
@@ -1246,6 +1282,8 @@ async function handleDelete() {
|
|
|
1246
1282
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1247
1283
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1248
1284
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1285
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1286
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1249
1287
|
/>
|
|
1250
1288
|
</TelaChatBody>
|
|
1251
1289
|
|
|
@@ -1297,7 +1335,9 @@ async function handleDelete() {
|
|
|
1297
1335
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1298
1336
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1299
1337
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1338
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1300
1339
|
centered
|
|
1340
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1301
1341
|
@send="handleSend"
|
|
1302
1342
|
@cancel="handleCancel"
|
|
1303
1343
|
/>
|
|
@@ -1354,7 +1394,9 @@ async function handleDelete() {
|
|
|
1354
1394
|
:show-cancel-button="resolvedFeatures.showCancelButton"
|
|
1355
1395
|
:hide-model-selector="!resolvedFeatures.showModelSelector"
|
|
1356
1396
|
:hide-reasoning-effort-selector="!resolvedFeatures.showReasoningEffortSelector"
|
|
1397
|
+
:execution-controls-disabled="!!modelUpdateInFlight || !!reasoningEffortUpdateInFlight"
|
|
1357
1398
|
has-disclaimer
|
|
1399
|
+
@select-execution-profile="selectExecutionProfile"
|
|
1358
1400
|
@send="handleSend"
|
|
1359
1401
|
@cancel="handleCancel"
|
|
1360
1402
|
/>
|
|
@@ -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_92: {}, __VLS_105: {
|
|
23
23
|
message: useChatAuth;
|
|
24
|
-
},
|
|
24
|
+
}, __VLS_118: {}, __VLS_127: {}, __VLS_191: {}, __VLS_210: {
|
|
25
25
|
message: useChatAuth;
|
|
26
|
-
},
|
|
26
|
+
}, __VLS_223: {};
|
|
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_92) => any;
|
|
31
31
|
} & {
|
|
32
|
-
'failed-message-actions'?: (props: typeof
|
|
32
|
+
'failed-message-actions'?: (props: typeof __VLS_105) => any;
|
|
33
33
|
} & {
|
|
34
|
-
'composer-bottom'?: (props: typeof
|
|
34
|
+
'composer-bottom'?: (props: typeof __VLS_118) => any;
|
|
35
35
|
} & {
|
|
36
|
-
'topbar-leading'?: (props: typeof
|
|
36
|
+
'topbar-leading'?: (props: typeof __VLS_127) => any;
|
|
37
37
|
} & {
|
|
38
|
-
'composer-bottom'?: (props: typeof
|
|
38
|
+
'composer-bottom'?: (props: typeof __VLS_191) => any;
|
|
39
39
|
} & {
|
|
40
|
-
'failed-message-actions'?: (props: typeof
|
|
40
|
+
'failed-message-actions'?: (props: typeof __VLS_210) => any;
|
|
41
41
|
} & {
|
|
42
|
-
'composer-bottom'?: (props: typeof
|
|
42
|
+
'composer-bottom'?: (props: typeof __VLS_223) => 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;
|
|
@@ -20,6 +20,7 @@ const props = defineProps({
|
|
|
20
20
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
21
21
|
availableModels: { type: Array, required: false },
|
|
22
22
|
defaultModel: { type: String, required: false },
|
|
23
|
+
executionControls: { type: Object, required: false },
|
|
23
24
|
defaultReasoningEffort: { type: null, required: false },
|
|
24
25
|
conversationCreatorFilter: { type: null, required: false },
|
|
25
26
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
@@ -86,6 +87,7 @@ provideEmbedConfig({
|
|
|
86
87
|
conversationScope: normalizedConversationScope,
|
|
87
88
|
defaultConversationCreatorFilter: computed(() => props.defaultConversationCreatorFilter),
|
|
88
89
|
availableModels: computed(() => props.availableModels),
|
|
90
|
+
executionControls: computed(() => props.executionControls),
|
|
89
91
|
defaultModel: computed(() => props.defaultModel),
|
|
90
92
|
defaultReasoningEffort: computed(() => props.defaultReasoningEffort),
|
|
91
93
|
conversationCreatorFilter: computed(() => props.conversationCreatorFilter),
|
|
@@ -12,6 +12,7 @@ const { hideSidebar = void 0, syncBrowserState = true, closeOnOutsideClick = tru
|
|
|
12
12
|
defaultConversationCreatorFilter: { type: null, required: false },
|
|
13
13
|
availableModels: { type: Array, required: false },
|
|
14
14
|
defaultModel: { type: String, required: false },
|
|
15
|
+
executionControls: { type: Object, required: false },
|
|
15
16
|
defaultReasoningEffort: { type: null, required: false },
|
|
16
17
|
conversationCreatorFilter: { type: null, required: false },
|
|
17
18
|
hideConversationCreatorFilter: { type: Boolean, required: false },
|
|
@@ -78,6 +79,7 @@ const sharedEmbedProps = computed(() => ({
|
|
|
78
79
|
conversationScope: props.conversationScope,
|
|
79
80
|
defaultConversationCreatorFilter: props.defaultConversationCreatorFilter,
|
|
80
81
|
availableModels: props.availableModels,
|
|
82
|
+
executionControls: props.executionControls,
|
|
81
83
|
defaultModel: props.defaultModel,
|
|
82
84
|
defaultReasoningEffort: props.defaultReasoningEffort,
|
|
83
85
|
conversationCreatorFilter: props.conversationCreatorFilter,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../execution-controls.js';
|
|
1
2
|
import type { DeepReadonly } from 'vue';
|
|
2
3
|
import type { Conversation, ConversationWithMessages, Message } from '../../../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { ConversationFile } from '../../../types/schemas/chat/files.js';
|
|
@@ -35,6 +36,7 @@ type __VLS_Props = {
|
|
|
35
36
|
showCancelButton?: boolean;
|
|
36
37
|
hideModelSelector?: boolean;
|
|
37
38
|
hideReasoningEffortSelector?: boolean;
|
|
39
|
+
executionControlsDisabled?: boolean;
|
|
38
40
|
showDebugOption?: boolean;
|
|
39
41
|
showOutdatedBadge?: boolean;
|
|
40
42
|
showOutdatedBanner?: boolean;
|
|
@@ -49,13 +51,13 @@ type __VLS_ModelProps = {
|
|
|
49
51
|
'selectedReasoningEffort'?: ChatReasoningEffort | null;
|
|
50
52
|
};
|
|
51
53
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
52
|
-
declare var __VLS_54: {},
|
|
54
|
+
declare var __VLS_54: {}, __VLS_100: {}, __VLS_102: {};
|
|
53
55
|
type __VLS_Slots = {} & {
|
|
54
56
|
loading?: (props: typeof __VLS_54) => any;
|
|
55
57
|
} & {
|
|
56
|
-
empty?: (props: typeof
|
|
58
|
+
empty?: (props: typeof __VLS_100) => any;
|
|
57
59
|
} & {
|
|
58
|
-
default?: (props: typeof
|
|
60
|
+
default?: (props: typeof __VLS_102) => any;
|
|
59
61
|
};
|
|
60
62
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
61
63
|
"update:selectedModel": (value: string | null) => any;
|
|
@@ -71,6 +73,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
71
73
|
selectConversation: (id: string) => any;
|
|
72
74
|
settings: () => any;
|
|
73
75
|
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
76
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
74
77
|
tabChange: (tab: TopbarTab) => any;
|
|
75
78
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
76
79
|
switchWorkspace: () => any;
|
|
@@ -92,6 +95,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
92
95
|
onSelectConversation?: ((id: string) => any) | undefined;
|
|
93
96
|
onSettings?: (() => any) | undefined;
|
|
94
97
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
98
|
+
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
95
99
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
96
100
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
97
101
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
@@ -41,6 +41,7 @@ const props = defineProps({
|
|
|
41
41
|
showCancelButton: { type: Boolean, required: false },
|
|
42
42
|
hideModelSelector: { type: Boolean, required: false },
|
|
43
43
|
hideReasoningEffortSelector: { type: Boolean, required: false },
|
|
44
|
+
executionControlsDisabled: { type: Boolean, required: false },
|
|
44
45
|
showDebugOption: { type: Boolean, required: false },
|
|
45
46
|
showOutdatedBadge: { type: Boolean, required: false },
|
|
46
47
|
showOutdatedBanner: { type: Boolean, required: false },
|
|
@@ -50,7 +51,7 @@ const props = defineProps({
|
|
|
50
51
|
workspaceSettings: { type: null, required: false },
|
|
51
52
|
workspaceSheetOpen: { type: Boolean, required: true }
|
|
52
53
|
});
|
|
53
|
-
const emit = defineEmits(["cancel", "cancelEditing", "copyLink", "debug", "delete", "dismissOutdatedBanner", "duplicate", "export", "newConversation", "rename", "saveTitle", "selectConversation", "send", "settings", "signout", "switchWorkspace", "tabChange", "update:drawerOpen", "update:editTitle", "update:workspaceSheetOpen"]);
|
|
54
|
+
const emit = defineEmits(["cancel", "selectExecutionProfile", "cancelEditing", "copyLink", "debug", "delete", "dismissOutdatedBanner", "duplicate", "export", "newConversation", "rename", "saveTitle", "selectConversation", "send", "settings", "signout", "switchWorkspace", "tabChange", "update:drawerOpen", "update:editTitle", "update:workspaceSheetOpen"]);
|
|
54
55
|
const embedConfig = useEmbedConfig();
|
|
55
56
|
const emptyStateLabels = computed(() => resolveEmptyStateLabels(embedConfig?.labels.value, props.currentUser?.name));
|
|
56
57
|
const selectedModel = defineModel("selectedModel", { type: [String, null], ...{ default: null } });
|
|
@@ -247,7 +248,9 @@ function startNewConversationFromOutdatedSettings() {
|
|
|
247
248
|
:show-cancel-button="showCancelButton"
|
|
248
249
|
:hide-model-selector="hideModelSelector"
|
|
249
250
|
:hide-reasoning-effort-selector="hideReasoningEffortSelector"
|
|
251
|
+
:execution-controls-disabled="executionControlsDisabled"
|
|
250
252
|
centered
|
|
253
|
+
@select-execution-profile="emit('selectExecutionProfile', $event)"
|
|
251
254
|
@send="(content, files, agentInputs) => emit('send', content, files, agentInputs)"
|
|
252
255
|
@cancel="emit('cancel')"
|
|
253
256
|
/>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../execution-controls.js';
|
|
1
2
|
import type { DeepReadonly } from 'vue';
|
|
2
3
|
import type { Conversation, ConversationWithMessages, Message } from '../../../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { ConversationFile } from '../../../types/schemas/chat/files.js';
|
|
@@ -35,6 +36,7 @@ type __VLS_Props = {
|
|
|
35
36
|
showCancelButton?: boolean;
|
|
36
37
|
hideModelSelector?: boolean;
|
|
37
38
|
hideReasoningEffortSelector?: boolean;
|
|
39
|
+
executionControlsDisabled?: boolean;
|
|
38
40
|
showDebugOption?: boolean;
|
|
39
41
|
showOutdatedBadge?: boolean;
|
|
40
42
|
showOutdatedBanner?: boolean;
|
|
@@ -49,13 +51,13 @@ type __VLS_ModelProps = {
|
|
|
49
51
|
'selectedReasoningEffort'?: ChatReasoningEffort | null;
|
|
50
52
|
};
|
|
51
53
|
type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
|
|
52
|
-
declare var __VLS_54: {},
|
|
54
|
+
declare var __VLS_54: {}, __VLS_100: {}, __VLS_102: {};
|
|
53
55
|
type __VLS_Slots = {} & {
|
|
54
56
|
loading?: (props: typeof __VLS_54) => any;
|
|
55
57
|
} & {
|
|
56
|
-
empty?: (props: typeof
|
|
58
|
+
empty?: (props: typeof __VLS_100) => any;
|
|
57
59
|
} & {
|
|
58
|
-
default?: (props: typeof
|
|
60
|
+
default?: (props: typeof __VLS_102) => any;
|
|
59
61
|
};
|
|
60
62
|
declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
61
63
|
"update:selectedModel": (value: string | null) => any;
|
|
@@ -71,6 +73,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
71
73
|
selectConversation: (id: string) => any;
|
|
72
74
|
settings: () => any;
|
|
73
75
|
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
76
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
74
77
|
tabChange: (tab: TopbarTab) => any;
|
|
75
78
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
76
79
|
switchWorkspace: () => any;
|
|
@@ -92,6 +95,7 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
92
95
|
onSelectConversation?: ((id: string) => any) | undefined;
|
|
93
96
|
onSettings?: (() => any) | undefined;
|
|
94
97
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
98
|
+
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
95
99
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
96
100
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
97
101
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionControls } from '../execution-controls.js';
|
|
1
2
|
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
2
3
|
import type { Component, DeepReadonly, MaybeRefOrGetter, Ref } from 'vue';
|
|
3
4
|
import type { ConversationCreatorFilter } from '../../types/schemas/chat/primitives.js';
|
|
@@ -15,6 +16,7 @@ export type EmbedConfig = {
|
|
|
15
16
|
conversationScope: Ref<string | null>;
|
|
16
17
|
defaultConversationCreatorFilter: Ref<ConversationCreatorFilter>;
|
|
17
18
|
availableModels: Ref<AvailableChatModels | undefined>;
|
|
19
|
+
executionControls: Ref<ChatExecutionControls | undefined>;
|
|
18
20
|
defaultModel: Ref<string | undefined>;
|
|
19
21
|
defaultReasoningEffort: Ref<ChatReasoningEffort | undefined>;
|
|
20
22
|
conversationCreatorFilter: Ref<ConversationCreatorFilter | undefined>;
|
|
@@ -38,6 +40,7 @@ type EmbedConfigInput = {
|
|
|
38
40
|
conversationScope?: MaybeRefOrGetter<string | null | undefined>;
|
|
39
41
|
defaultConversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | null | undefined>;
|
|
40
42
|
availableModels?: MaybeRefOrGetter<AvailableChatModels | undefined>;
|
|
43
|
+
executionControls?: MaybeRefOrGetter<ChatExecutionControls | undefined>;
|
|
41
44
|
defaultModel?: MaybeRefOrGetter<string | undefined>;
|
|
42
45
|
defaultReasoningEffort?: MaybeRefOrGetter<ChatReasoningEffort | undefined>;
|
|
43
46
|
conversationCreatorFilter?: MaybeRefOrGetter<ConversationCreatorFilter | undefined>;
|
|
@@ -23,6 +23,7 @@ function useGlobalEmbedConfigState() {
|
|
|
23
23
|
conversationScope: useState("chat-embed-config-conversation-scope", () => null),
|
|
24
24
|
defaultConversationCreatorFilter: useState("chat-embed-config-default-conversation-creator-filter", () => void 0),
|
|
25
25
|
availableModels: useState("chat-embed-config-available-models", () => void 0),
|
|
26
|
+
executionControls: useState("chat-embed-config-execution-controls", () => void 0),
|
|
26
27
|
defaultModel: useState("chat-embed-config-default-model", () => void 0),
|
|
27
28
|
defaultReasoningEffort: useState("chat-embed-config-default-reasoning-effort", () => void 0),
|
|
28
29
|
conversationCreatorFilter: useState("chat-embed-config-conversation-creator-filter", () => void 0),
|
|
@@ -48,6 +49,7 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
48
49
|
conversationScope: computed(() => normalizeConversationScope(toValue(input.conversationScope))),
|
|
49
50
|
defaultConversationCreatorFilter: computed(() => toValue(input.defaultConversationCreatorFilter) ?? "all"),
|
|
50
51
|
availableModels: computed(() => toValue(input.availableModels)),
|
|
52
|
+
executionControls: computed(() => toValue(input.executionControls)),
|
|
51
53
|
defaultModel: computed(() => toValue(input.defaultModel)),
|
|
52
54
|
defaultReasoningEffort: computed(() => toValue(input.defaultReasoningEffort)),
|
|
53
55
|
conversationCreatorFilter: computed(() => toValue(input.conversationCreatorFilter)),
|
|
@@ -74,6 +76,7 @@ export function provideEmbedConfig(input, options = {}) {
|
|
|
74
76
|
globalConfig.conversationScope.value = config.conversationScope.value;
|
|
75
77
|
globalConfig.defaultConversationCreatorFilter.value = config.defaultConversationCreatorFilter.value;
|
|
76
78
|
globalConfig.availableModels.value = config.availableModels.value;
|
|
79
|
+
globalConfig.executionControls.value = config.executionControls.value;
|
|
77
80
|
globalConfig.defaultModel.value = config.defaultModel.value;
|
|
78
81
|
globalConfig.defaultReasoningEffort.value = config.defaultReasoningEffort.value;
|
|
79
82
|
globalConfig.conversationCreatorFilter.value = config.conversationCreatorFilter.value;
|
|
@@ -107,6 +110,7 @@ export function useEmbedConfig() {
|
|
|
107
110
|
conversationScope: computed(() => globalConfig.conversationScope.value),
|
|
108
111
|
defaultConversationCreatorFilter: computed(() => globalConfig.defaultConversationCreatorFilter.value ?? "all"),
|
|
109
112
|
availableModels: computed(() => globalConfig.availableModels.value),
|
|
113
|
+
executionControls: computed(() => globalConfig.executionControls.value),
|
|
110
114
|
defaultModel: computed(() => globalConfig.defaultModel.value),
|
|
111
115
|
defaultReasoningEffort: computed(() => globalConfig.defaultReasoningEffort.value),
|
|
112
116
|
conversationCreatorFilter: computed(() => globalConfig.conversationCreatorFilter.value),
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { ChatReasoningEffort } from '../types/schemas/chat/models.js';
|
|
2
|
+
import type { ChatFeatureConfig } from './feature-config.js';
|
|
3
|
+
export type ChatExecutionProfile = {
|
|
4
|
+
model: string;
|
|
5
|
+
reasoningEffort: ChatReasoningEffort | null;
|
|
6
|
+
};
|
|
7
|
+
export type ChatExecutionControls = {
|
|
8
|
+
mode: 'hidden';
|
|
9
|
+
} | {
|
|
10
|
+
mode: 'simple';
|
|
11
|
+
profiles: {
|
|
12
|
+
default: ChatExecutionProfile;
|
|
13
|
+
deep: ChatExecutionProfile;
|
|
14
|
+
};
|
|
15
|
+
} | {
|
|
16
|
+
mode: 'advanced';
|
|
17
|
+
showModelSelector?: boolean;
|
|
18
|
+
showReasoningEffortSelector?: boolean;
|
|
19
|
+
};
|
|
20
|
+
export declare function resolveChatExecutionControls(controls?: ChatExecutionControls, features?: ChatFeatureConfig): ChatExecutionControls;
|
|
21
|
+
export declare function resolveChatExecutionMode(profiles: Extract<ChatExecutionControls, {
|
|
22
|
+
mode: 'simple';
|
|
23
|
+
}>['profiles'], selection: {
|
|
24
|
+
model: string | null;
|
|
25
|
+
reasoningEffort?: ChatReasoningEffort | null;
|
|
26
|
+
}): 'default' | 'deep' | 'custom';
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export function resolveChatExecutionControls(controls, features) {
|
|
2
|
+
if (controls && controls.mode !== "advanced")
|
|
3
|
+
return controls;
|
|
4
|
+
const flags = controls ?? features;
|
|
5
|
+
return {
|
|
6
|
+
mode: "advanced",
|
|
7
|
+
showModelSelector: flags?.showModelSelector ?? true,
|
|
8
|
+
showReasoningEffortSelector: flags?.showReasoningEffortSelector ?? true
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export function resolveChatExecutionMode(profiles, selection) {
|
|
12
|
+
for (const mode of ["default", "deep"]) {
|
|
13
|
+
const profile = profiles[mode];
|
|
14
|
+
if (profile.model === selection.model && profile.reasoningEffort === (selection.reasoningEffort ?? null))
|
|
15
|
+
return mode;
|
|
16
|
+
}
|
|
17
|
+
return "custom";
|
|
18
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ChatExecutionControls } from './execution-controls.js';
|
|
1
2
|
/** Optional feature toggles the host passes per embed instance. */
|
|
2
3
|
export type ChatFeatureConfig = {
|
|
3
4
|
/** Cost section in the conversation details panel, with per-conversation token and cost stats. Defaults to true. */
|
|
@@ -13,11 +14,13 @@ export type ChatFeatureConfig = {
|
|
|
13
14
|
/** `@` / `/` shortcut hints below the empty-state composer. Defaults to true. */
|
|
14
15
|
showPromptInputHints?: boolean;
|
|
15
16
|
/**
|
|
17
|
+
* @deprecated Use executionControls: { mode: 'advanced', showModelSelector: false }.
|
|
16
18
|
* Model picker in the composer toolbar. Defaults to true. Hiding it keeps model
|
|
17
19
|
* resolution unchanged: `defaultModel`, the conversation's saved model, or the agent default.
|
|
18
20
|
*/
|
|
19
21
|
showModelSelector?: boolean;
|
|
20
22
|
/**
|
|
23
|
+
* @deprecated Use executionControls: { mode: 'advanced', showReasoningEffortSelector: false }.
|
|
21
24
|
* Reasoning effort picker in the composer toolbar. Defaults to true. Hiding it keeps
|
|
22
25
|
* effort resolution unchanged: `defaultReasoningEffort`, the conversation's saved effort,
|
|
23
26
|
* or the agent default.
|
|
@@ -34,4 +37,4 @@ export type ResolvedChatFeatureConfig = {
|
|
|
34
37
|
showModelSelector: boolean;
|
|
35
38
|
showReasoningEffortSelector: boolean;
|
|
36
39
|
};
|
|
37
|
-
export declare function resolveChatFeatures(features?: Partial<ChatFeatureConfig
|
|
40
|
+
export declare function resolveChatFeatures(features?: Partial<ChatFeatureConfig>, executionControls?: ChatExecutionControls): ResolvedChatFeatureConfig;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
import { resolveChatExecutionControls } from "./execution-controls.js";
|
|
2
|
+
export function resolveChatFeatures(features, executionControls) {
|
|
3
|
+
const controls = resolveChatExecutionControls(executionControls, features);
|
|
2
4
|
return {
|
|
3
5
|
showUsageTab: features?.showUsageTab ?? true,
|
|
4
6
|
showDebugOption: features?.showDebugOption ?? true,
|
|
@@ -6,7 +8,7 @@ export function resolveChatFeatures(features) {
|
|
|
6
8
|
showTtft: features?.showTtft ?? true,
|
|
7
9
|
chatOutboundQueue: features?.chatOutboundQueue ?? true,
|
|
8
10
|
showPromptInputHints: features?.showPromptInputHints ?? true,
|
|
9
|
-
showModelSelector:
|
|
10
|
-
showReasoningEffortSelector:
|
|
11
|
+
showModelSelector: controls.mode === "advanced" && controls.showModelSelector === true,
|
|
12
|
+
showReasoningEffortSelector: controls.mode === "advanced" && controls.showReasoningEffortSelector === true
|
|
11
13
|
};
|
|
12
14
|
}
|
|
@@ -5,6 +5,7 @@ import type { WorkspaceSettingsResponse as WorkspaceSettings } from '../types/sc
|
|
|
5
5
|
import type { TelaAgentExecutionInput } from '../types/schemas/integrations/tela-agent-api.js';
|
|
6
6
|
import type { ConversationCreatorFilter } from '../types/schemas/chat/primitives.js';
|
|
7
7
|
import type { ChatLoadingMessageMode } from './loading-messages.js';
|
|
8
|
+
import type { ChatExecutionControls } from './execution-controls.js';
|
|
8
9
|
import type { ChatFeatureConfig } from './feature-config.js';
|
|
9
10
|
import type { ChatCitationsConfig } from '../citations/types.js';
|
|
10
11
|
import type { MessageFeedbackConfig, MessageFeedbackRating } from '../messages/composables/chat-feedback.js';
|
|
@@ -95,6 +96,8 @@ export type ChatEmbedSharedProps = {
|
|
|
95
96
|
* Initial model for untouched drafts. Existing conversations and explicit selections take precedence.
|
|
96
97
|
*/
|
|
97
98
|
defaultModel?: string;
|
|
99
|
+
/** Execution controls. Omission preserves legacy feature flags; simple profiles supply draft defaults. */
|
|
100
|
+
executionControls?: ChatExecutionControls;
|
|
98
101
|
/**
|
|
99
102
|
* Initial effort for untouched drafts. Omission preserves automatic reasoning;
|
|
100
103
|
* an explicit user selection (including null) takes precedence.
|
|
@@ -25,6 +25,10 @@ export declare function useChat(options?: Parameters<typeof useSharedChat>[0]):
|
|
|
25
25
|
setConversationModel: (model: string | null) => void;
|
|
26
26
|
pendingModelSelection: any;
|
|
27
27
|
setConversationReasoningEffort: (reasoningEffort: ChatReasoningEffort | null) => void;
|
|
28
|
+
setConversationExecutionProfile: (profile: {
|
|
29
|
+
model: string | null;
|
|
30
|
+
reasoningEffort: import("../../../embed/execution-controls.js").ChatExecutionProfile["reasoningEffort"];
|
|
31
|
+
}) => void;
|
|
28
32
|
pendingReasoningEffortSelection: any;
|
|
29
33
|
sendMessage: (content: string, files?: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[], prepare?: (signal: AbortSignal) => Promise<{
|
|
30
34
|
wakeSessionId?: string;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
2
|
+
import { type ChatExecutionControls, type ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
profiles: Extract<ChatExecutionControls, {
|
|
5
|
+
mode: 'simple';
|
|
6
|
+
}>['profiles'];
|
|
7
|
+
model: string | null;
|
|
8
|
+
reasoningEffort: ChatReasoningEffort | null;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
12
|
+
select: (profile: ChatExecutionProfile) => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
14
|
+
onSelect?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { resolveChatExecutionMode } from "../../embed/execution-controls";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
profiles: { type: null, required: true },
|
|
5
|
+
model: { type: [String, null], required: true },
|
|
6
|
+
reasoningEffort: { type: null, required: true },
|
|
7
|
+
disabled: { type: Boolean, required: false }
|
|
8
|
+
});
|
|
9
|
+
const emit = defineEmits(["select"]);
|
|
10
|
+
const options = [
|
|
11
|
+
{ value: "default", label: "Padr\xE3o", description: "Para as tarefas do dia a dia." },
|
|
12
|
+
{ value: "deep", label: "Aprofundar", description: "Dedica mais racioc\xEDnio a tarefas complexas. Pode demorar mais." }
|
|
13
|
+
];
|
|
14
|
+
const mode = computed(() => resolveChatExecutionMode(props.profiles, props));
|
|
15
|
+
const label = computed(() => mode.value === "custom" ? "Personalizado" : options.find((option) => option.value === mode.value).label);
|
|
16
|
+
function select(value) {
|
|
17
|
+
if (!props.disabled && (value === "default" || value === "deep"))
|
|
18
|
+
emit("select", { ...props.profiles[value] });
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<template>
|
|
23
|
+
<TelaSelectMenu
|
|
24
|
+
:model-value="mode === 'custom' ? void 0 : mode"
|
|
25
|
+
:options="options"
|
|
26
|
+
:disabled="disabled"
|
|
27
|
+
content-class="w-280px max-w-[calc(100vw-32px)]"
|
|
28
|
+
@update:model-value="select"
|
|
29
|
+
>
|
|
30
|
+
<template #trigger>
|
|
31
|
+
<TelaSelectMenuTrigger
|
|
32
|
+
data-testid="chat-execution-mode-selector"
|
|
33
|
+
:aria-label="`Modo de resposta: ${label}`"
|
|
34
|
+
class="w-auto border-0 rounded-8px bg-transparent shadow-none gap-6px pl-10px body-14-medium"
|
|
35
|
+
>
|
|
36
|
+
<span whitespace-nowrap>{{ label }}</span>
|
|
37
|
+
</TelaSelectMenuTrigger>
|
|
38
|
+
</template>
|
|
39
|
+
</TelaSelectMenu>
|
|
40
|
+
</template>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
2
|
+
import { type ChatExecutionControls, type ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
profiles: Extract<ChatExecutionControls, {
|
|
5
|
+
mode: 'simple';
|
|
6
|
+
}>['profiles'];
|
|
7
|
+
model: string | null;
|
|
8
|
+
reasoningEffort: ChatReasoningEffort | null;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
12
|
+
select: (profile: ChatExecutionProfile) => any;
|
|
13
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
14
|
+
onSelect?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
15
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
16
|
+
declare const _default: typeof __VLS_export;
|
|
17
|
+
export default _default;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
1
2
|
import type { DeepReadonly } from 'vue';
|
|
2
3
|
import type { Message } from '../../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
@@ -23,6 +24,7 @@ type __VLS_Props = {
|
|
|
23
24
|
/** Absent means shown, so internal callers keep the picker unless they opt out. */
|
|
24
25
|
hideModelSelector?: boolean;
|
|
25
26
|
hideReasoningEffortSelector?: boolean;
|
|
27
|
+
executionControlsDisabled?: boolean;
|
|
26
28
|
sendBlocked?: boolean;
|
|
27
29
|
};
|
|
28
30
|
declare function addFiles(files: File[], inputName?: string): void;
|
|
@@ -47,9 +49,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
47
49
|
} & {
|
|
48
50
|
cancel: () => any;
|
|
49
51
|
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
52
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
50
53
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
54
|
onCancel?: (() => any) | undefined;
|
|
52
55
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
56
|
+
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
53
57
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
54
58
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
55
59
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
<script setup>
|
|
2
|
+
import ChatExecutionModeSelector from "./chat-execution-mode-selector.vue";
|
|
3
|
+
import { useEmbedConfig } from "../../embed/composables/embed-config";
|
|
2
4
|
import ChatModelSelector from "./chat-model-selector.vue";
|
|
3
5
|
import { inject, unref } from "vue";
|
|
4
6
|
import { useResizeObserver } from "@vueuse/core";
|
|
@@ -28,14 +30,16 @@ const props = defineProps({
|
|
|
28
30
|
showCancelButton: { type: Boolean, required: false },
|
|
29
31
|
hideModelSelector: { type: Boolean, required: false },
|
|
30
32
|
hideReasoningEffortSelector: { type: Boolean, required: false },
|
|
33
|
+
executionControlsDisabled: { type: Boolean, required: false },
|
|
31
34
|
sendBlocked: { type: Boolean, required: false }
|
|
32
35
|
});
|
|
33
|
-
const emit = defineEmits(["send", "cancel"]);
|
|
36
|
+
const emit = defineEmits(["send", "cancel", "selectExecutionProfile"]);
|
|
34
37
|
const selectedModel = defineModel("selectedModel", { type: [String, null], ...{ default: null } });
|
|
35
38
|
const composerExtension = inject(CHAT_COMPOSER_EXTENSION_KEY, null);
|
|
36
39
|
const selectedReasoningEffort = defineModel("selectedReasoningEffort", { type: null, ...{ default: null } });
|
|
37
40
|
const { uploadFiles, uploading, uploadError } = useFileUpload();
|
|
38
41
|
const isCancelEnabled = computed(() => props.showCancelButton === true);
|
|
42
|
+
const executionControls = useEmbedConfig()?.executionControls;
|
|
39
43
|
const content = ref("");
|
|
40
44
|
const promptTextareaRef = ref(null);
|
|
41
45
|
const editorRef = computed(() => promptTextareaRef.value?.el ?? null);
|
|
@@ -424,7 +428,14 @@ function handleInput() {
|
|
|
424
428
|
}
|
|
425
429
|
function handlePaste(e) {
|
|
426
430
|
e.preventDefault();
|
|
431
|
+
if (isLocked.value)
|
|
432
|
+
return;
|
|
433
|
+
const files = Array.from(e.clipboardData?.files ?? []);
|
|
434
|
+
if (files.length > 0)
|
|
435
|
+
addFiles(files);
|
|
427
436
|
const text = e.clipboardData?.getData("text/plain") ?? "";
|
|
437
|
+
if (!text)
|
|
438
|
+
return;
|
|
428
439
|
const sel = window.getSelection();
|
|
429
440
|
if (!sel || sel.rangeCount === 0)
|
|
430
441
|
return;
|
|
@@ -786,6 +797,15 @@ defineExpose({
|
|
|
786
797
|
</TelaChatPromptInputTools>
|
|
787
798
|
|
|
788
799
|
<TelaChatPromptInputActions>
|
|
800
|
+
<ChatExecutionModeSelector
|
|
801
|
+
v-if="executionControls?.mode === 'simple'"
|
|
802
|
+
:profiles="executionControls.profiles"
|
|
803
|
+
:model="selectedModel"
|
|
804
|
+
:reasoning-effort="selectedReasoningEffort"
|
|
805
|
+
:disabled="isLocked || executionControlsDisabled"
|
|
806
|
+
@select="emit('selectExecutionProfile', $event)"
|
|
807
|
+
@click.stop
|
|
808
|
+
/>
|
|
789
809
|
<ChatReasoningEffortSelector
|
|
790
810
|
v-if="!hideReasoningEffortSelector"
|
|
791
811
|
v-model="selectedReasoningEffort"
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
1
2
|
import type { DeepReadonly } from 'vue';
|
|
2
3
|
import type { Message } from '../../types/schemas/chat/conversations.js';
|
|
3
4
|
import type { ChatReasoningEffort } from '../../types/schemas/chat/models.js';
|
|
@@ -23,6 +24,7 @@ type __VLS_Props = {
|
|
|
23
24
|
/** Absent means shown, so internal callers keep the picker unless they opt out. */
|
|
24
25
|
hideModelSelector?: boolean;
|
|
25
26
|
hideReasoningEffortSelector?: boolean;
|
|
27
|
+
executionControlsDisabled?: boolean;
|
|
26
28
|
sendBlocked?: boolean;
|
|
27
29
|
};
|
|
28
30
|
declare function addFiles(files: File[], inputName?: string): void;
|
|
@@ -47,9 +49,11 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
|
|
|
47
49
|
} & {
|
|
48
50
|
cancel: () => any;
|
|
49
51
|
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
52
|
+
selectExecutionProfile: (profile: ChatExecutionProfile) => any;
|
|
50
53
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
51
54
|
onCancel?: (() => any) | undefined;
|
|
52
55
|
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
56
|
+
onSelectExecutionProfile?: ((profile: ChatExecutionProfile) => any) | undefined;
|
|
53
57
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
54
58
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
55
59
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ChatExecutionProfile } from '../../embed/execution-controls.js';
|
|
1
2
|
import type { ReasoningItem } from '../../types/schemas/integrations/agent-api.js';
|
|
2
3
|
import { type DeepReadonly, type MaybeRefOrGetter, type Ref } from 'vue';
|
|
3
4
|
import type { Conversation, ConversationWithMessages, Message } from '../../types/schemas/chat/conversations.js';
|
|
@@ -47,6 +48,10 @@ export declare function useChat(options?: {
|
|
|
47
48
|
setConversationModel: (model: string | null) => void;
|
|
48
49
|
pendingModelSelection: any;
|
|
49
50
|
setConversationReasoningEffort: (reasoningEffort: ChatReasoningEffort | null) => void;
|
|
51
|
+
setConversationExecutionProfile: (profile: {
|
|
52
|
+
model: string | null;
|
|
53
|
+
reasoningEffort: ChatExecutionProfile["reasoningEffort"];
|
|
54
|
+
}) => void;
|
|
50
55
|
pendingReasoningEffortSelection: any;
|
|
51
56
|
sendMessage: (content: string, files?: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[], prepare?: (signal: AbortSignal) => Promise<{
|
|
52
57
|
wakeSessionId?: string;
|
|
@@ -411,15 +411,26 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
411
411
|
if (!chatApi.conversationV2Enabled)
|
|
412
412
|
void pollMessages();
|
|
413
413
|
};
|
|
414
|
+
const simpleExecutionProfiles = computed(() => {
|
|
415
|
+
const controls = embedConfig?.executionControls?.value;
|
|
416
|
+
return controls?.mode === "simple" ? controls.profiles : null;
|
|
417
|
+
});
|
|
418
|
+
const pendingSimpleSelectionBuckets = useState("chat-pending-simple-selection", () => ({}));
|
|
414
419
|
const pendingModelBuckets = useState("chat-pending-model-selection", () => ({}));
|
|
415
420
|
const pendingModelSelection = computed({
|
|
416
421
|
get: () => {
|
|
417
422
|
const buckets = pendingModelBuckets.value;
|
|
418
423
|
if (chatScope.value in buckets)
|
|
419
424
|
return buckets[chatScope.value] ?? null;
|
|
425
|
+
if (simpleExecutionProfiles.value)
|
|
426
|
+
return simpleExecutionProfiles.value.default.model;
|
|
420
427
|
return embedConfig?.defaultModel?.value ?? (adapter.defaultModel === void 0 ? defaultChatModel : adapter.defaultModel);
|
|
421
428
|
},
|
|
422
429
|
set: (value) => {
|
|
430
|
+
pendingSimpleSelectionBuckets.value[chatScope.value] = {
|
|
431
|
+
...pendingSimpleSelectionBuckets.value[chatScope.value],
|
|
432
|
+
model: !!simpleExecutionProfiles.value
|
|
433
|
+
};
|
|
423
434
|
pendingModelBuckets.value = {
|
|
424
435
|
...pendingModelBuckets.value,
|
|
425
436
|
[chatScope.value]: value
|
|
@@ -434,14 +445,22 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
434
445
|
};
|
|
435
446
|
const pendingReasoningEffortBuckets = useState("chat-pending-reasoning-effort-selection", () => ({}));
|
|
436
447
|
const pendingReasoningEffortSelection = computed({
|
|
437
|
-
get: () => chatScope.value in pendingReasoningEffortBuckets.value ? pendingReasoningEffortBuckets.value[chatScope.value] ?? null : embedConfig?.defaultReasoningEffort?.value ?? null,
|
|
448
|
+
get: () => chatScope.value in pendingReasoningEffortBuckets.value ? pendingReasoningEffortBuckets.value[chatScope.value] ?? null : simpleExecutionProfiles.value ? simpleExecutionProfiles.value.default.reasoningEffort : embedConfig?.defaultReasoningEffort?.value ?? null,
|
|
438
449
|
set: (value) => {
|
|
450
|
+
pendingSimpleSelectionBuckets.value[chatScope.value] = {
|
|
451
|
+
...pendingSimpleSelectionBuckets.value[chatScope.value],
|
|
452
|
+
reasoningEffort: !!simpleExecutionProfiles.value
|
|
453
|
+
};
|
|
439
454
|
pendingReasoningEffortBuckets.value = {
|
|
440
455
|
...pendingReasoningEffortBuckets.value,
|
|
441
456
|
[chatScope.value]: value
|
|
442
457
|
};
|
|
443
458
|
}
|
|
444
459
|
});
|
|
460
|
+
const setConversationExecutionProfile = (profile) => {
|
|
461
|
+
if (currentConversation.value)
|
|
462
|
+
currentConversation.value = { ...currentConversation.value, ...profile };
|
|
463
|
+
};
|
|
445
464
|
const setConversationReasoningEffort = (reasoningEffort) => {
|
|
446
465
|
const conversation = currentConversation.value;
|
|
447
466
|
if (!conversation || (conversation.reasoningEffort ?? null) === reasoningEffort)
|
|
@@ -776,6 +795,12 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
776
795
|
void flushOutboundQueue();
|
|
777
796
|
});
|
|
778
797
|
const clearConversation = () => {
|
|
798
|
+
const simpleSelection = pendingSimpleSelectionBuckets.value[chatScope.value];
|
|
799
|
+
if (simpleExecutionProfiles.value || simpleSelection?.model || simpleSelection?.reasoningEffort) {
|
|
800
|
+
delete pendingModelBuckets.value[chatScope.value];
|
|
801
|
+
delete pendingReasoningEffortBuckets.value[chatScope.value];
|
|
802
|
+
delete pendingSimpleSelectionBuckets.value[chatScope.value];
|
|
803
|
+
}
|
|
779
804
|
runtimeBlocked.value = false;
|
|
780
805
|
stopPolling();
|
|
781
806
|
gateController?.abort();
|
|
@@ -1029,6 +1054,7 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
1029
1054
|
setConversationModel,
|
|
1030
1055
|
pendingModelSelection,
|
|
1031
1056
|
setConversationReasoningEffort,
|
|
1057
|
+
setConversationExecutionProfile,
|
|
1032
1058
|
pendingReasoningEffortSelection,
|
|
1033
1059
|
sendMessage,
|
|
1034
1060
|
flushOutboundQueue,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type { ChatCitationsConfig, CitationMeta, CitationRef, } from '../citations/types.js';
|
|
2
|
+
export type { ChatExecutionControls, ChatExecutionProfile } from '../embed/execution-controls.js';
|
|
2
3
|
export type { ChatFeatureConfig } from '../embed/feature-config.js';
|
|
3
4
|
export type { AvailableChatModels, ChatActor, ChatEmbedSharedProps, ChatEmbedVariant, ChatEmbedVariantProps, ChatLabels, ChatSidebarConfig, ChatSuggestion, DefaultChatEmbedProps, MeistrariChatEmbedProps, TelaAgentChatEmbedProps, } from '../embed/types.js';
|
|
4
5
|
export type { ChatActionPayload } from '../messages/composables/chat-action.js';
|