@@ -9,7 +9,11 @@ import { buildSlashItems, filterCommands, parseSlash } from '../lib/slashCommand
99import type { FileItem } from ' ./MentionMenu.vue' ;
1010import type { ActivationBadges , ConversationStatus , PermissionMode , QueuedPromptView } from ' ../types' ;
1111import type { AppModel , AppSkill , ThinkingLevel } from ' ../api/types' ;
12- import { modelThinkingAvailability } from ' ../lib/modelThinking' ;
12+ import {
13+ coerceThinkingForModel ,
14+ effortLevelsForModel ,
15+ modelThinkingAvailability ,
16+ } from ' ../lib/modelThinking' ;
1317import { formatTokens } from ' ../lib/formatTokens' ;
1418
1519// ---------------------------------------------------------------------------
@@ -745,7 +749,7 @@ function toggleDropdown(): void {
745749 if (dropdownOpen .value ) {
746750 const rect = modelPillRef .value ?.getBoundingClientRect ();
747751 modelDropdownStyle .value = rect
748- ? { maxHeight: ` ${Math .max (160 , rect .top - 4 - 12 )}px ` }
752+ ? { maxHeight: ` ${Math .min ( 360 , Math . max (160 , rect .top - 4 - 12 ) )}px ` }
749753 : {};
750754 permDropdownOpen .value = false ;
751755 document .addEventListener (' click' , onDocClick , true );
@@ -817,15 +821,16 @@ const currentModel = computed(() => {
817821 );
818822});
819823const thinkingAvailability = computed (() => modelThinkingAvailability (currentModel .value ));
820- const thinkingToggleable = computed (() => thinkingAvailability .value === ' toggle' );
821- const thinkingOn = computed (() => {
822- if (thinkingAvailability .value === ' always-on' ) return true ;
823- if (thinkingAvailability .value === ' unsupported' ) return false ;
824- return (props .thinking ?? ' off' ) !== ' off' ;
825- });
826- function toggleThinking(): void {
827- if (! thinkingToggleable .value ) return ;
828- emit (' setThinking' , thinkingOn .value ? ' off' : ' high' );
824+ const effortLevels = computed (() => effortLevelsForModel (currentModel .value ));
825+ const currentEffort = computed <ThinkingLevel >(() =>
826+ coerceThinkingForModel (currentModel .value , props .thinking ?? ' off' ),
827+ );
828+ function effortLabel(level : ThinkingLevel ): string {
829+ return t (` status.effortLevels.${level } ` );
830+ }
831+ function selectEffort(level : ThinkingLevel ): void {
832+ emit (' setThinking' , level );
833+ closeDropdown ();
829834}
830835
831836// Plan toggle
@@ -1200,7 +1205,7 @@ function selectModel(modelId: string): void {
12001205 @keydown.space.prevent =" toggleDropdown"
12011206 >
12021207 <b >{{ status.model }}</b >
1203- <span v-if =" thinkingOn " class =" think-suffix" >{{ t('composer.thinkingSuffix') }}</span >
1208+ <span v-if =" thinkingAvailability !== 'unsupported' " class =" think-suffix" >{{ ` · ${effortLabel(currentEffort)}` }}</span >
12041209 <svg class =" cv" viewBox =" 0 0 16 16" width =" 11" height =" 11" fill =" none" stroke =" currentColor" stroke-width =" 1.8" stroke-linecap =" round" stroke-linejoin =" round" aria-hidden =" true" ><path d =" M4 6l4 4 4-4" /></svg >
12051210 </span >
12061211 </div >
@@ -1242,19 +1247,21 @@ function selectModel(modelId: string): void {
12421247
12431248 <div v-if =" providerModels.length > 0" class =" md-divider" />
12441249
1245- <!-- Thinking toggle -->
1246- <button
1247- class =" md-row md-row-toggle"
1248- role =" menuitem"
1249- :class =" { 'is-on': thinkingOn, 'is-disabled': !thinkingToggleable }"
1250- :disabled =" !thinkingToggleable"
1251- @click =" toggleThinking()"
1252- >
1253- <span class =" md-check" ><svg v-if =" thinkingOn" viewBox =" 0 0 16 16" width =" 13" height =" 13" fill =" none" stroke =" currentColor" stroke-width =" 1.8" stroke-linecap =" round" stroke-linejoin =" round" aria-hidden =" true" ><path d =" M3 8.5l3.5 3.5L13 4.5" /></svg ></span >
1254- <span class =" md-name" >{{ t('status.thinkingLabel') }}</span >
1255- <span v-if =" thinkingAvailability === 'always-on'" class =" md-note" >{{ t('status.planOn') }}</span >
1256- <span v-else-if =" thinkingAvailability === 'unsupported'" class =" md-note" >{{ t('status.modeNotSupported') }}</span >
1257- </button >
1250+ <!-- Thinking effort -->
1251+ <div class =" md-section" >{{ t('status.effortLabel') }}</div >
1252+ <div v-if =" thinkingAvailability === 'unsupported'" class =" md-cache-note" >{{ t('status.modeNotSupported') }}</div >
1253+ <template v-else >
1254+ <button
1255+ v-for =" level in effortLevels"
1256+ :key =" level"
1257+ class =" md-row"
1258+ role =" menuitem"
1259+ @click =" selectEffort(level)"
1260+ >
1261+ <span class =" md-check" ><svg v-if =" level === currentEffort" viewBox =" 0 0 16 16" width =" 13" height =" 13" fill =" none" stroke =" currentColor" stroke-width =" 1.8" stroke-linecap =" round" stroke-linejoin =" round" aria-hidden =" true" ><path d =" M3 8.5l3.5 3.5L13 4.5" /></svg ></span >
1262+ <span class =" md-name" >{{ effortLabel(level) }}</span >
1263+ </button >
1264+ </template >
12581265
12591266 <div class =" md-divider" />
12601267 <div class =" md-cache-note" >{{ t('status.cacheNote') }}</div >
0 commit comments