diff --git a/apps/desktop/src/app/chat/composer/model-pill.tsx b/apps/desktop/src/app/chat/composer/model-pill.tsx
index b5a6e976805b..2a26db4094c9 100644
--- a/apps/desktop/src/app/chat/composer/model-pill.tsx
+++ b/apps/desktop/src/app/chat/composer/model-pill.tsx
@@ -11,7 +11,7 @@ import { useI18n } from '@/i18n'
import { ChevronDown } from '@/lib/icons'
import { formatModelStatusLabel } from '@/lib/model-status-label'
import { cn } from '@/lib/utils'
-import { $currentModelSource, setModelPickerOpen } from '@/store/session'
+import { $currentModelSource, $defaultReasoningEffort, setModelPickerOpen } from '@/store/session'
import type { ChatBarState } from './types'
@@ -48,6 +48,7 @@ export function ModelPill({
const fastMode = useStore(view.$fast)
const reasoningEffort = useStore(view.$reasoningEffort)
const modelSource = useStore($currentModelSource)
+ const defaultEffort = useStore($defaultReasoningEffort)
const runtimeId = useStore(view.$runtimeId)
const [open, setOpen] = useState(false)
@@ -68,7 +69,9 @@ export function ModelPill({
) : (
<>
{currentModel.trim() ? (
- {formatModelStatusLabel(currentModel, { fastMode, reasoningEffort })}
+
+ {formatModelStatusLabel(currentModel, { defaultEffort, fastMode, reasoningEffort })}
+
) : (
)}
diff --git a/apps/desktop/src/i18n/ar.ts b/apps/desktop/src/i18n/ar.ts
index 2d61c399998f..01f018d65936 100644
--- a/apps/desktop/src/i18n/ar.ts
+++ b/apps/desktop/src/i18n/ar.ts
@@ -1986,8 +1986,7 @@ export const ar = defineLocale({
noModels: 'لا توجد نماذج',
editModels: 'تحرير النماذج',
refreshModels: 'تحديث النماذج',
- fast: 'سريع',
- medium: 'متوسط'
+ fast: 'سريع'
},
modelOptions: {
noOptions: 'لا توجد خيارات لهذا النموذج',
diff --git a/apps/desktop/src/i18n/en.ts b/apps/desktop/src/i18n/en.ts
index 12d15e9657c4..25a6fa82fb61 100644
--- a/apps/desktop/src/i18n/en.ts
+++ b/apps/desktop/src/i18n/en.ts
@@ -2306,8 +2306,7 @@ export const en: Translations = {
noModels: 'No models found',
editModels: 'Edit Models…',
refreshModels: 'Refresh Models',
- fast: 'Fast',
- medium: 'Med'
+ fast: 'Fast'
},
modelOptions: {
noOptions: 'No options for this model',
diff --git a/apps/desktop/src/i18n/ja.ts b/apps/desktop/src/i18n/ja.ts
index 90d65ad5901a..75cfe0feaf8a 100644
--- a/apps/desktop/src/i18n/ja.ts
+++ b/apps/desktop/src/i18n/ja.ts
@@ -2178,8 +2178,7 @@ export const ja = defineLocale({
noModels: 'モデルが見つかりません',
editModels: 'モデルを編集…',
refreshModels: 'モデルを更新',
- fast: '高速',
- medium: '中'
+ fast: '高速'
},
modelOptions: {
noOptions: 'このモデルにはオプションがありません',
diff --git a/apps/desktop/src/i18n/types.ts b/apps/desktop/src/i18n/types.ts
index 41417a4cf338..928493ec05a4 100644
--- a/apps/desktop/src/i18n/types.ts
+++ b/apps/desktop/src/i18n/types.ts
@@ -1915,7 +1915,6 @@ export interface Translations {
editModels: string
refreshModels: string
fast: string
- medium: string
}
modelOptions: {
noOptions: string
diff --git a/apps/desktop/src/i18n/zh-hant.ts b/apps/desktop/src/i18n/zh-hant.ts
index 2772852eee51..90240c358a0e 100644
--- a/apps/desktop/src/i18n/zh-hant.ts
+++ b/apps/desktop/src/i18n/zh-hant.ts
@@ -2105,8 +2105,7 @@ export const zhHant = defineLocale({
noModels: '找不到模型',
editModels: '編輯模型…',
refreshModels: '重新整理模型',
- fast: '快速',
- medium: '中'
+ fast: '快速'
},
modelOptions: {
noOptions: '此模型沒有可用選項',
diff --git a/apps/desktop/src/i18n/zh.ts b/apps/desktop/src/i18n/zh.ts
index 68cbbb77ad4a..f9f4c92a7748 100644
--- a/apps/desktop/src/i18n/zh.ts
+++ b/apps/desktop/src/i18n/zh.ts
@@ -2483,8 +2483,7 @@ export const zh: Translations = {
noModels: '未找到模型',
editModels: '编辑模型…',
refreshModels: '刷新模型',
- fast: '快速',
- medium: '中'
+ fast: '快速'
},
modelOptions: {
noOptions: '此模型没有可用选项',
diff --git a/apps/desktop/src/lib/model-status-label.test.ts b/apps/desktop/src/lib/model-status-label.test.ts
index cc499c86d565..c0a1f867c22e 100644
--- a/apps/desktop/src/lib/model-status-label.test.ts
+++ b/apps/desktop/src/lib/model-status-label.test.ts
@@ -34,9 +34,16 @@ describe('model-status-label', () => {
)
})
- it('always surfaces the effort (default medium) so the level is visible', () => {
+ it('falls back to the profile default effort, then to medium', () => {
expect(formatModelStatusLabel('openai/gpt-5.5', { reasoningEffort: 'medium' })).toBe('GPT-5.5 · Med')
expect(formatModelStatusLabel('openai/gpt-5.5')).toBe('GPT-5.5 · Med')
+ // No session-level effort → the configured profile default is advertised,
+ // not Hermes' built-in medium.
+ expect(formatModelStatusLabel('openai/gpt-5.5', { defaultEffort: 'high' })).toBe('GPT-5.5 · High')
+ // An explicit session effort still wins over the profile default.
+ expect(formatModelStatusLabel('openai/gpt-5.5', { defaultEffort: 'high', reasoningEffort: 'low' })).toBe(
+ 'GPT-5.5 · Low'
+ )
})
it('returns just the placeholder name when there is no model', () => {
diff --git a/apps/desktop/src/lib/model-status-label.ts b/apps/desktop/src/lib/model-status-label.ts
index a1b28b8a4c58..1c6a7850dc12 100644
--- a/apps/desktop/src/lib/model-status-label.ts
+++ b/apps/desktop/src/lib/model-status-label.ts
@@ -99,10 +99,12 @@ export function displayModelName(model: string): string {
return modelDisplayParts(model).name
}
-/** Status bar trigger label — model name plus the live session state (effort/fast). */
+/** Status bar trigger label — model name plus the live session state (effort/fast).
+ * `defaultEffort` is the profile's configured level, used when the surface has
+ * no explicit effort so the label never advertises a default the agent won't use. */
export function formatModelStatusLabel(
model: string,
- options?: { fastMode?: boolean; reasoningEffort?: string }
+ options?: { defaultEffort?: string; fastMode?: boolean; reasoningEffort?: string }
): string {
const name = displayModelName(model)
@@ -118,9 +120,9 @@ export function formatModelStatusLabel(
parts.push('Fast')
}
- // Always surface the effort (empty = Hermes default of medium) so the
- // current reasoning level is visible at a glance, not just when non-default.
- parts.push(reasoningEffortLabel(options?.reasoningEffort ?? '') || 'Med')
+ // Always surface the effort so the current reasoning level is visible at a
+ // glance, not just when non-default.
+ parts.push(reasoningEffortLabel(options?.reasoningEffort || options?.defaultEffort || 'medium'))
return `${name} · ${parts.join(' ')}`
}