From d8a0fd027abb123f47307461a38c4ad65844bbdc Mon Sep 17 00:00:00 2001 From: dimakis Date: Mon, 31 Aug 2026 17:04:29 +0100 Subject: [PATCH 1/3] feat(models): add Opus 4.8 and Sonnet 5, remove stale models Update available model list to match current Vertex AI inventory: - Add Claude Opus 4.8 + Max variant - Add Claude Sonnet 5 - Remove Opus 4.7 and Opus 4.5 (not provisioned on new project) - Update tests to cover new models Co-Authored-By: Claude Opus 4.6 --- frontend/src/pages/ChatView.tsx | 6 +++--- frontend/src/pages/DesktopChatView.tsx | 6 ++++-- server/__tests__/model-spec.test.ts | 4 ++-- server/chat.ts | 6 +++--- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/frontend/src/pages/ChatView.tsx b/frontend/src/pages/ChatView.tsx index 7907e004..6dfe3d15 100644 --- a/frontend/src/pages/ChatView.tsx +++ b/frontend/src/pages/ChatView.tsx @@ -223,10 +223,10 @@ export function ChatView() { onChange={(e) => setModel(e.target.value)} disabled={messages.running} > - - + + - + diff --git a/frontend/src/pages/DesktopChatView.tsx b/frontend/src/pages/DesktopChatView.tsx index 1e85533b..cc0e65ce 100644 --- a/frontend/src/pages/DesktopChatView.tsx +++ b/frontend/src/pages/DesktopChatView.tsx @@ -198,10 +198,12 @@ export function DesktopChatView() { onChange={(e) => setModel(e.target.value)} disabled={messages.running} > - - + + + +
diff --git a/server/__tests__/model-spec.test.ts b/server/__tests__/model-spec.test.ts index 095ec4e5..5cc42712 100644 --- a/server/__tests__/model-spec.test.ts +++ b/server/__tests__/model-spec.test.ts @@ -38,7 +38,7 @@ describe('resolveThinking', () => { }); it('returns adaptive for plain opus model', () => { - expect(resolveThinking('claude-opus-4-7')).toEqual({ type: 'adaptive' }); + expect(resolveThinking('claude-opus-4-8')).toEqual({ type: 'adaptive' }); }); it('returns adaptive for opus 4-6', () => { @@ -46,7 +46,7 @@ describe('resolveThinking', () => { }); it('returns 128k budget for opus :max', () => { - expect(resolveThinking('claude-opus-4-7:max')).toEqual({ + expect(resolveThinking('claude-opus-4-8:max')).toEqual({ type: 'enabled', budgetTokens: 128_000, }); diff --git a/server/chat.ts b/server/chat.ts index 6442db70..57a823f9 100644 --- a/server/chat.ts +++ b/server/chat.ts @@ -366,10 +366,10 @@ export function getRepoConfig() { } export const AVAILABLE_MODELS = [ - { id: 'claude-opus-4-7', label: 'Opus 4.7', desc: 'Adaptive thinking' }, - { id: 'claude-opus-4-7:max', label: 'Opus 4.7 Max', desc: 'Max thinking (128k)' }, + { id: 'claude-opus-4-8', label: 'Opus 4.8', desc: 'Latest Opus' }, + { id: 'claude-opus-4-8:max', label: 'Opus 4.8 Max', desc: 'Max thinking (128k)' }, { id: 'claude-opus-4-6', label: 'Opus 4.6', desc: 'Previous Opus' }, - { id: 'claude-opus-4-5', label: 'Opus 4.5', desc: 'Legacy Opus' }, + { id: 'claude-sonnet-5', label: 'Sonnet 5', desc: 'Latest Sonnet' }, { id: 'claude-sonnet-4-6', label: 'Sonnet 4.6', desc: 'Balanced' }, { id: 'claude-sonnet-4-5', label: 'Sonnet 4.5', desc: 'Previous Sonnet' }, { id: 'claude-haiku-4-5', label: 'Haiku 4.5', desc: 'Fastest' }, From 831bcc6b506ffac292e3340196ef77536af7670a Mon Sep 17 00:00:00 2001 From: dimakis Date: Tue, 1 Sep 2026 22:14:21 +0100 Subject: [PATCH 2/3] fix(models): remove stale claude-opus-4-7 references Update JSDoc, test fixtures, and constants comment to reference claude-opus-4-8 consistently after the model list update. Co-Authored-By: Claude Sonnet 4.6 --- frontend/src/lib/constants.ts | 10 +++++----- server/__tests__/model-spec.test.ts | 14 +++++++------- server/chat.ts | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/frontend/src/lib/constants.ts b/frontend/src/lib/constants.ts index 501aa92c..dbbf01e7 100644 --- a/frontend/src/lib/constants.ts +++ b/frontend/src/lib/constants.ts @@ -9,11 +9,11 @@ export const WS_RECONNECT_POLL_MS = 5_000; export const SCROLL_NEAR_BOTTOM_PX = 150; export const SCROLL_RESTORE_DELAY_MS = 100; export const LAST_SESSION_KEY = 'mitzo-last-session'; -// Default model for new sessions. Opus 4.6 is used rather than 4.7 because -// 4.7 is not yet available on every supported provider (e.g. Vertex AI at -// time of writing) — picking a widely-available model keeps the out-of-box -// experience functional. Users with access can still select Opus 4.7 from -// the dropdown; the selection persists per-browser. +// Default model for new sessions. Opus 4.6 is used rather than 4.8 because +// 4.8 is not yet available on every supported provider — picking a widely- +// available model keeps the out-of-box experience functional. Users with +// access can still select Opus 4.8 from the dropdown; the selection persists +// per-browser. export const DEFAULT_MODEL = 'claude-opus-4-6'; // --- Tool grouping --- diff --git a/server/__tests__/model-spec.test.ts b/server/__tests__/model-spec.test.ts index 5cc42712..163662ef 100644 --- a/server/__tests__/model-spec.test.ts +++ b/server/__tests__/model-spec.test.ts @@ -7,26 +7,26 @@ describe('parseModelSpec', () => { }); it('parses a plain model ID', () => { - expect(parseModelSpec('claude-opus-4-7')).toEqual({ - model: 'claude-opus-4-7', + expect(parseModelSpec('claude-opus-4-8')).toEqual({ + model: 'claude-opus-4-8', effort: undefined, }); }); it('splits model and effort on colon', () => { - expect(parseModelSpec('claude-opus-4-7:max')).toEqual({ - model: 'claude-opus-4-7', + expect(parseModelSpec('claude-opus-4-8:max')).toEqual({ + model: 'claude-opus-4-8', effort: 'max', }); }); it('handles trailing colon as empty effort', () => { - expect(parseModelSpec('claude-opus-4-7:')).toEqual({ model: 'claude-opus-4-7', effort: '' }); + expect(parseModelSpec('claude-opus-4-8:')).toEqual({ model: 'claude-opus-4-8', effort: '' }); }); it('handles multiple colons — only splits on first', () => { - expect(parseModelSpec('claude-opus-4-7:max:extra')).toEqual({ - model: 'claude-opus-4-7', + expect(parseModelSpec('claude-opus-4-8:max:extra')).toEqual({ + model: 'claude-opus-4-8', effort: 'max:extra', }); }); diff --git a/server/chat.ts b/server/chat.ts index 57a823f9..d915362d 100644 --- a/server/chat.ts +++ b/server/chat.ts @@ -375,7 +375,7 @@ export const AVAILABLE_MODELS = [ { id: 'claude-haiku-4-5', label: 'Haiku 4.5', desc: 'Fastest' }, ]; -/** Split "claude-opus-4-7:max" → { model: "claude-opus-4-7", effort: "max" } */ +/** Split "claude-opus-4-8:max" → { model: "claude-opus-4-8", effort: "max" } */ export function parseModelSpec(spec?: string): { model: string; effort: string | undefined } { if (!spec) return { model: '', effort: undefined }; const idx = spec.indexOf(':'); From 1f20306701c30a0a2eda40343cb82fd2760a0f8f Mon Sep 17 00:00:00 2001 From: dimakis Date: Tue, 1 Sep 2026 22:23:08 +0100 Subject: [PATCH 3/3] fix(models): fix remaining stale claude-opus-4-7 references in tests Update ws-handler-v2 and store test fixtures, add resolveThinking test case for claude-sonnet-5 naming pattern. Co-Authored-By: Claude Sonnet 4.6 --- packages/client/__tests__/store.test.ts | 4 ++-- server/__tests__/model-spec.test.ts | 9 ++++++++- server/__tests__/ws-handler-v2.test.ts | 8 ++++---- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/packages/client/__tests__/store.test.ts b/packages/client/__tests__/store.test.ts index 2fba7283..fb7e8c5e 100644 --- a/packages/client/__tests__/store.test.ts +++ b/packages/client/__tests__/store.test.ts @@ -792,11 +792,11 @@ describe('interruptMessage', () => { store.getState().sendMessage('first'); lastWs.simulateMessage({ type: 'session_id', sessionId: 'sess-int3' }); - store.getState().interruptMessage('urgent', { model: 'claude-opus-4-7' }); + store.getState().interruptMessage('urgent', { model: 'claude-opus-4-8' }); const interrupts = lastWs.parsedSent().filter((m) => m.type === 'interrupt'); expect(interrupts).toHaveLength(1); - expect(interrupts[0].model).toBe('claude-opus-4-7'); + expect(interrupts[0].model).toBe('claude-opus-4-8'); }); it('does not include model field when both opts and config are null', () => { diff --git a/server/__tests__/model-spec.test.ts b/server/__tests__/model-spec.test.ts index 163662ef..76816c25 100644 --- a/server/__tests__/model-spec.test.ts +++ b/server/__tests__/model-spec.test.ts @@ -52,13 +52,20 @@ describe('resolveThinking', () => { }); }); - it('returns 10k budget for sonnet', () => { + it('returns 10k budget for sonnet 4-6', () => { expect(resolveThinking('claude-sonnet-4-6')).toEqual({ type: 'enabled', budgetTokens: 10_000, }); }); + it('returns 10k budget for sonnet 5', () => { + expect(resolveThinking('claude-sonnet-5')).toEqual({ + type: 'enabled', + budgetTokens: 10_000, + }); + }); + it('returns undefined for haiku', () => { expect(resolveThinking('claude-haiku-4-5')).toBeUndefined(); }); diff --git a/server/__tests__/ws-handler-v2.test.ts b/server/__tests__/ws-handler-v2.test.ts index bad44d60..eb4f2031 100644 --- a/server/__tests__/ws-handler-v2.test.ts +++ b/server/__tests__/ws-handler-v2.test.ts @@ -2364,7 +2364,7 @@ describe('handleInterruptV2 forwarding', () => { sessionId: 'sess-resume', prompt: 'urgent', clientMsgId: 'i-resume', - model: 'claude-opus-4-7', + model: 'claude-opus-4-8', }, ctx, ); @@ -2373,7 +2373,7 @@ describe('handleInterruptV2 forwarding', () => { transport, 'c2:sess-resume', 'urgent', - expect.objectContaining({ resume: 'sess-resume', model: 'claude-opus-4-7' }), + expect.objectContaining({ resume: 'sess-resume', model: 'claude-opus-4-8' }), ); }); @@ -2435,7 +2435,7 @@ describe('handleInterruptV2 forwarding', () => { sessionId: 'sess-precedence', prompt: 'override', clientMsgId: 'i-precedence', - model: 'claude-opus-4-7', + model: 'claude-opus-4-8', }, ctx, ); @@ -2444,7 +2444,7 @@ describe('handleInterruptV2 forwarding', () => { transport, 'c4:sess-precedence', 'override', - expect.objectContaining({ resume: 'sess-precedence', model: 'claude-opus-4-7' }), + expect.objectContaining({ resume: 'sess-precedence', model: 'claude-opus-4-8' }), ); });