From 667a094ffd1a86f68ef15abdded4109c410813f1 Mon Sep 17 00:00:00 2001 From: bradygaster Date: Mon, 16 Mar 2026 05:16:52 -0700 Subject: [PATCH] feat: update default model selection to claude-sonnet-4.6 and gpt-5.4 - Bump standard code/prompt default: claude-sonnet-4.5 -> claude-sonnet-4.6 - Bump visual default: claude-opus-4.5 -> claude-opus-4.6 - Add gpt-5.4 and gpt-5.3-codex to standard tier and fallback chains - Update code specialist override: gpt-5.2-codex -> gpt-5.3-codex - Update FALLBACK_CHAINS.standard to start with claude-sonnet-4.6 - Add claude-sonnet-4.6, gpt-5.4, gpt-5.3-codex to MODEL_CATALOG - Keep claude-haiku-4.5 unchanged (no 4.6 exists) - Update SKILL.md, squad.agent.md, and all source/test files Closes #322 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .github/agents/squad.agent.md | 8 ++--- .squad/skills/model-selection/SKILL.md | 30 ++++++++--------- .../squad-sdk/src/agents/model-selector.ts | 6 ++-- packages/squad-sdk/src/config/models.ts | 32 +++++++++++++++++-- packages/squad-sdk/src/runtime/benchmarks.ts | 6 ++-- packages/squad-sdk/src/runtime/constants.ts | 8 +++-- test/agents.test.ts | 18 ++++++----- test/compat-v041.test.ts | 4 +-- test/config.test.ts | 2 +- test/init.test.ts | 2 +- test/models.test.ts | 2 +- 11 files changed, 75 insertions(+), 43 deletions(-) diff --git a/.github/agents/squad.agent.md b/.github/agents/squad.agent.md index f612fd95b..1dfc3609d 100644 --- a/.github/agents/squad.agent.md +++ b/.github/agents/squad.agent.md @@ -3,14 +3,14 @@ name: Squad description: "Your AI team. Describe what you're building, get a team of specialists that live in your repo." --- - + You are **Squad (Coordinator)** — the orchestrator for this project's AI team. ### Coordinator Identity - **Name:** Squad (Coordinator) -- **Version:** 0.8.25-build.5 (see HTML comment above — this value is stamped during install/upgrade). Include it as `Squad v0.8.25-build.5` in your first response of each session (e.g., in the acknowledgment or greeting). +- **Version:** 0.8.25-build.10 (see HTML comment above — this value is stamped during install/upgrade). Include it as `Squad v0.8.25-build.5` in your first response of each session (e.g., in the acknowledgment or greeting). - **Role:** Agent orchestration, handoff enforcement, reviewer gating - **Inputs:** User request, repository state, `.squad/decisions.md` - **Outputs owned:** Final assembled artifacts, orchestration log (via Scribe) @@ -292,9 +292,9 @@ For read-only queries, use the explore agent: `agent_type: "explore"` with `"You **Core rules (always loaded):** - 4-layer hierarchy: User Override → Charter Preference → Task-Aware Auto → Default (haiku) - Governing principle: **cost first, unless code is being written** -- Code tasks → `claude-sonnet-4.5` (standard), non-code → `claude-haiku-4.5` (fast) +- Code tasks → `claude-sonnet-4.6` (standard), non-code → `claude-haiku-4.5` (fast) - Fallback chains: silently retry within tier, never fall UP, log but don't surface to user -- Always include model in spawn acknowledgment: `🔧 Fenster (claude-sonnet-4.5) — task` +- Always include model in spawn acknowledgment: `🔧 Fenster (claude-sonnet-4.6) — task` ### Client Compatibility diff --git a/.squad/skills/model-selection/SKILL.md b/.squad/skills/model-selection/SKILL.md index 9b66ae298..611941bab 100644 --- a/.squad/skills/model-selection/SKILL.md +++ b/.squad/skills/model-selection/SKILL.md @@ -24,8 +24,8 @@ Check these layers in order — first match wins: | Task Output | Model | Tier | Rule | |-------------|-------|------|------| -| Writing code (implementation, refactoring, test code, bug fixes) | `claude-sonnet-4.5` | Standard | Quality and accuracy matter for code. Use standard tier. | -| Writing prompts or agent designs (structured text that functions like code) | `claude-sonnet-4.5` | Standard | Prompts are executable — treat like code. | +| Writing code (implementation, refactoring, test code, bug fixes) | `claude-sonnet-4.6` | Standard | Quality and accuracy matter for code. Use standard tier. | +| Writing prompts or agent designs (structured text that functions like code) | `claude-sonnet-4.6` | Standard | Prompts are executable — treat like code. | | NOT writing code (docs, planning, triage, logs, changelogs, mechanical ops) | `claude-haiku-4.5` | Fast | Cost first. Haiku handles non-code tasks. | | Visual/design work requiring image analysis | `claude-opus-4.5` | Premium | Vision capability required. Overrides cost rule. | @@ -33,12 +33,12 @@ Check these layers in order — first match wins: | Role | Default Model | Why | Override When | |------|--------------|-----|---------------| -| Core Dev / Backend / Frontend | `claude-sonnet-4.5` | Writes code — quality first | Heavy code gen → `gpt-5.2-codex` | -| Tester / QA | `claude-sonnet-4.5` | Writes test code — quality first | Simple test scaffolding → `claude-haiku-4.5` | +| Core Dev / Backend / Frontend | `claude-sonnet-4.6` | Writes code — quality first | Heavy code gen → `gpt-5.3-codex` | +| Tester / QA | `claude-sonnet-4.6` | Writes test code — quality first | Simple test scaffolding → `claude-haiku-4.5` | | Lead / Architect | auto (per-task) | Mixed: code review needs quality, planning needs cost | Architecture proposals → premium; triage/planning → haiku | | Prompt Engineer | auto (per-task) | Mixed: prompt design is like code, research is not | Prompt architecture → sonnet; research/analysis → haiku | -| Copilot SDK Expert | `claude-sonnet-4.5` | Technical analysis that often touches code | Pure research → `claude-haiku-4.5` | -| Designer / Visual | `claude-opus-4.5` | Vision-capable model required | — (never downgrade — vision is non-negotiable) | +| Copilot SDK Expert | `claude-sonnet-4.6` | Technical analysis that often touches code | Pure research → `claude-haiku-4.5` | +| Designer / Visual | `claude-opus-4.6` | Vision-capable model required | — (never downgrade — vision is non-negotiable) | | DevRel / Writer | `claude-haiku-4.5` | Docs and writing — not code | — | | Scribe / Logger | `claude-haiku-4.5` | Mechanical file ops — cheapest possible | — (never bump Scribe) | | Git / Release | `claude-haiku-4.5` | Mechanical ops — changelogs, tags, version bumps | — (never bump mechanical ops) | @@ -46,7 +46,7 @@ Check these layers in order — first match wins: **Task complexity adjustments** (apply at most ONE — no cascading): - **Bump UP to premium:** architecture proposals, reviewer gates, security audits, multi-agent coordination (output feeds 3+ agents) - **Bump DOWN to fast/cheap:** typo fixes, renames, boilerplate, scaffolding, changelogs, version bumps -- **Switch to code specialist (`gpt-5.2-codex`):** large multi-file refactors, complex implementation from spec, heavy code generation (500+ lines) +- **Switch to code specialist (`gpt-5.3-codex`):** large multi-file refactors, complex implementation from spec, heavy code generation (500+ lines) - **Switch to analytical diversity (`gemini-3-pro-preview`):** code reviews where a second perspective helps, security reviews, architecture reviews after a rejection **Layer 4 — Default:** If nothing else matched, use `claude-haiku-4.5`. Cost wins when in doubt, unless code is being produced. @@ -56,8 +56,8 @@ Check these layers in order — first match wins: If a spawn fails because the selected model is unavailable (plan restriction, org policy, rate limit, deprecation, or any other reason), silently retry with the next model in the chain. Do NOT tell the user about fallback attempts. Maximum 3 retries before jumping to the nuclear fallback. ``` -Premium: claude-opus-4.6 → claude-opus-4.6-fast → claude-opus-4.5 → claude-sonnet-4.5 → (omit model param) -Standard: claude-sonnet-4.5 → gpt-5.2-codex → claude-sonnet-4 → gpt-5.2 → (omit model param) +Premium: claude-opus-4.6 → claude-opus-4.6-fast → claude-opus-4.5 → claude-sonnet-4.6 → (omit model param) +Standard: claude-sonnet-4.6 → gpt-5.4 → claude-sonnet-4.5 → gpt-5.3-codex → claude-sonnet-4 → (omit model param) Fast: claude-haiku-4.5 → gpt-5.1-codex-mini → gpt-4.1 → gpt-5-mini → (omit model param) ``` @@ -81,7 +81,7 @@ prompt: | ... ``` -Only set `model` when it differs from the platform default (`claude-sonnet-4.5`). If the resolved model IS `claude-sonnet-4.5`, you MAY omit the `model` parameter — the platform uses it as default. +Only set `model` when it differs from the platform default (`claude-sonnet-4.6`). If the resolved model IS `claude-sonnet-4.6`, you MAY omit the `model` parameter — the platform uses it as default. If you've exhausted the fallback chain and reached nuclear fallback, omit the `model` parameter entirely. @@ -90,8 +90,8 @@ If you've exhausted the fallback chain and reached nuclear fallback, omit the `m When spawning, include the model in your acknowledgment: ``` -🔧 Fenster (claude-sonnet-4.5) — refactoring auth module -🎨 Redfoot (claude-opus-4.5 · vision) — designing color system +🔧 Fenster (claude-sonnet-4.6) — refactoring auth module +🎨 Redfoot (claude-opus-4.6 · vision) — designing color system 📋 Scribe (claude-haiku-4.5 · fast) — logging session ⚡ Keaton (claude-opus-4.6 · bumped for architecture) — reviewing proposal 📝 McManus (claude-haiku-4.5 · fast) — updating docs @@ -102,7 +102,7 @@ Include tier annotation only when the model was bumped or a specialist was chose ### Valid Models **Premium:** `claude-opus-4.6`, `claude-opus-4.6-fast`, `claude-opus-4.5` -**Standard:** `claude-sonnet-4.5`, `claude-sonnet-4`, `gpt-5.2-codex`, `gpt-5.2`, `gpt-5.1-codex-max`, `gpt-5.1-codex`, `gpt-5.1`, `gpt-5`, `gemini-3-pro-preview` +**Standard:** `claude-sonnet-4.6`, `claude-sonnet-4.5`, `claude-sonnet-4`, `gpt-5.4`, `gpt-5.3-codex`, `gpt-5.2-codex`, `gpt-5.2`, `gpt-5.1-codex-max`, `gpt-5.1-codex`, `gpt-5.1`, `gpt-5`, `gemini-3-pro-preview` **Fast/Cheap:** `claude-haiku-4.5`, `gpt-5.1-codex-mini`, `gpt-5-mini`, `gpt-4.1` ## Examples @@ -110,8 +110,8 @@ Include tier annotation only when the model was bumped or a specialist was chose **Example 1: Backend dev writing API endpoints** - Role: Backend Dev - Task: "implement REST endpoints for user management" -- Layer 3 decision: writing code → `claude-sonnet-4.5` (standard tier) -- Spawn: `🔧 Fenster (claude-sonnet-4.5) — implementing user API endpoints` +- Layer 3 decision: writing code → `claude-sonnet-4.6` (standard tier) +- Spawn: `🔧 Fenster (claude-sonnet-4.6) — implementing user API endpoints` **Example 2: User override** - User says: "use haiku for everything this session" diff --git a/packages/squad-sdk/src/agents/model-selector.ts b/packages/squad-sdk/src/agents/model-selector.ts index 3c202edca..2e2eee305 100644 --- a/packages/squad-sdk/src/agents/model-selector.ts +++ b/packages/squad-sdk/src/agents/model-selector.ts @@ -104,7 +104,7 @@ function selectModelForTask(taskType: TaskType): ResolvedModel | undefined { switch (taskType) { case 'code': return { - model: 'claude-sonnet-4.5', + model: 'claude-sonnet-4.6', tier: 'standard', source: 'task-auto', fallbackChain: [...MODELS.FALLBACK_CHAINS.standard], @@ -112,7 +112,7 @@ function selectModelForTask(taskType: TaskType): ResolvedModel | undefined { case 'prompt': return { - model: 'claude-sonnet-4.5', + model: 'claude-sonnet-4.6', tier: 'standard', source: 'task-auto', fallbackChain: [...MODELS.FALLBACK_CHAINS.standard], @@ -120,7 +120,7 @@ function selectModelForTask(taskType: TaskType): ResolvedModel | undefined { case 'visual': return { - model: 'claude-opus-4.5', + model: 'claude-opus-4.6', tier: 'premium', source: 'task-auto', fallbackChain: [...MODELS.FALLBACK_CHAINS.premium], diff --git a/packages/squad-sdk/src/config/models.ts b/packages/squad-sdk/src/config/models.ts index 1d3154f2f..92639dee3 100644 --- a/packages/squad-sdk/src/config/models.ts +++ b/packages/squad-sdk/src/config/models.ts @@ -75,6 +75,16 @@ export const MODEL_CATALOG: ModelInfo[] = [ }, // Standard tier - balanced quality, speed, cost + { + id: 'claude-sonnet-4.6', + tier: 'standard', + provider: 'anthropic', + family: 'claude', + vision: true, + useCases: ['code generation', 'test writing', 'refactoring', 'prompt engineering'], + cost: 5, + speed: 7 + }, { id: 'claude-sonnet-4.5', tier: 'standard', @@ -94,6 +104,24 @@ export const MODEL_CATALOG: ModelInfo[] = [ cost: 4, speed: 7 }, + { + id: 'gpt-5.4', + tier: 'standard', + provider: 'openai', + family: 'gpt', + useCases: ['general purpose', 'code generation', 'analysis'], + cost: 6, + speed: 7 + }, + { + id: 'gpt-5.3-codex', + tier: 'standard', + provider: 'openai', + family: 'gpt', + useCases: ['heavy code generation', 'multi-file refactors'], + cost: 5, + speed: 6 + }, { id: 'gpt-5.2-codex', tier: 'standard', @@ -201,8 +229,8 @@ export const MODEL_CATALOG: ModelInfo[] = [ * Default fallback chains per tier from squad.agent.md. */ export const DEFAULT_FALLBACK_CHAINS: Record = { - premium: ['claude-opus-4.6', 'claude-opus-4.6-fast', 'claude-opus-4.5', 'claude-sonnet-4.5'], - standard: ['claude-sonnet-4.5', 'gpt-5.2-codex', 'claude-sonnet-4', 'gpt-5.2'], + premium: ['claude-opus-4.6', 'claude-opus-4.6-fast', 'claude-opus-4.5', 'claude-sonnet-4.6'], + standard: ['claude-sonnet-4.6', 'gpt-5.4', 'claude-sonnet-4.5', 'gpt-5.3-codex', 'claude-sonnet-4', 'gpt-5.2'], fast: ['claude-haiku-4.5', 'gpt-5.1-codex-mini', 'gpt-4.1', 'gpt-5-mini'] }; diff --git a/packages/squad-sdk/src/runtime/benchmarks.ts b/packages/squad-sdk/src/runtime/benchmarks.ts index 4132b5ba8..755f1cf76 100644 --- a/packages/squad-sdk/src/runtime/benchmarks.ts +++ b/packages/squad-sdk/src/runtime/benchmarks.ts @@ -221,7 +221,7 @@ export class BenchmarkSuite { // Simulate config parsing: build and validate a config-like object const config = { version: '1.0.0', - models: { defaultModel: 'claude-sonnet-4.5', defaultTier: 'standard', fallbackChains: { premium: [], standard: [], fast: [] } }, + models: { defaultModel: 'claude-sonnet-4.6', defaultTier: 'standard', fallbackChains: { premium: [], standard: [], fast: [] } }, routing: { rules: [{ workType: 'feature-dev', agents: ['@coordinator'] }] }, }; JSON.parse(JSON.stringify(config)); @@ -263,8 +263,8 @@ export class BenchmarkSuite { private modelSelectionOp(): void { // Simulate model selection logic const tiers = { - premium: ['claude-opus-4.6', 'gpt-5.2'], - standard: ['claude-sonnet-4.5', 'gpt-5.1-codex'], + premium: ['claude-opus-4.6', 'gpt-5.4'], + standard: ['claude-sonnet-4.6', 'gpt-5.3-codex'], fast: ['claude-haiku-4.5', 'gpt-5-mini'], }; const role = 'developer'; diff --git a/packages/squad-sdk/src/runtime/constants.ts b/packages/squad-sdk/src/runtime/constants.ts index af9da7044..03e5eac01 100644 --- a/packages/squad-sdk/src/runtime/constants.ts +++ b/packages/squad-sdk/src/runtime/constants.ts @@ -11,7 +11,7 @@ export const MODELS = { /** Default model for config files and new projects (env-overridable) */ - DEFAULT: process.env['SQUAD_DEFAULT_MODEL'] ?? 'claude-sonnet-4.5', + DEFAULT: process.env['SQUAD_DEFAULT_MODEL'] ?? 'claude-sonnet-4.6', /** Default model for model-selector Layer 4 — cost-first */ SELECTOR_DEFAULT: 'claude-haiku-4.5', @@ -25,11 +25,13 @@ export const MODELS = { 'claude-opus-4.6', 'claude-opus-4.6-fast', 'claude-opus-4.5', - 'claude-sonnet-4.5', + 'claude-sonnet-4.6', ], standard: [ + 'claude-sonnet-4.6', + 'gpt-5.4', 'claude-sonnet-4.5', - 'gpt-5.2-codex', + 'gpt-5.3-codex', 'claude-sonnet-4', 'gpt-5.2', ], diff --git a/test/agents.test.ts b/test/agents.test.ts index dbb92c043..a3f8d1a54 100644 --- a/test/agents.test.ts +++ b/test/agents.test.ts @@ -208,7 +208,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { expect(result.source).not.toBe('charter'); expect(result.source).toBe('task-auto'); - expect(result.model).toBe('claude-sonnet-4.5'); + expect(result.model).toBe('claude-sonnet-4.6'); }); it('should prefer user override over charter', () => { @@ -233,7 +233,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); - expect(result.model).toBe('claude-sonnet-4.5'); + expect(result.model).toBe('claude-sonnet-4.6'); expect(result.tier).toBe('standard'); expect(result.source).toBe('task-auto'); }); @@ -245,7 +245,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); - expect(result.model).toBe('claude-sonnet-4.5'); + expect(result.model).toBe('claude-sonnet-4.6'); expect(result.tier).toBe('standard'); expect(result.source).toBe('task-auto'); }); @@ -257,7 +257,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); - expect(result.model).toBe('claude-opus-4.5'); + expect(result.model).toBe('claude-opus-4.6'); expect(result.tier).toBe('premium'); expect(result.source).toBe('task-auto'); }); @@ -328,7 +328,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { 'claude-opus-4.6', 'claude-opus-4.6-fast', 'claude-opus-4.5', - 'claude-sonnet-4.5', + 'claude-sonnet-4.6', ]); }); @@ -340,8 +340,10 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); expect(result.fallbackChain).toEqual([ + 'claude-sonnet-4.6', + 'gpt-5.4', 'claude-sonnet-4.5', - 'gpt-5.2-codex', + 'gpt-5.3-codex', 'claude-sonnet-4', 'gpt-5.2', ]); @@ -418,7 +420,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); expect(result.source).toBe('task-auto'); - expect(result.model).toBe('claude-sonnet-4.5'); + expect(result.model).toBe('claude-sonnet-4.6'); }); it('should include agentRole in context without affecting resolution', () => { @@ -429,7 +431,7 @@ describe('Per-Agent Model Selection (M1-9)', () => { const result = resolveModel(options); - expect(result.model).toBe('claude-sonnet-4.5'); + expect(result.model).toBe('claude-sonnet-4.6'); expect(result.source).toBe('task-auto'); }); }); diff --git a/test/compat-v041.test.ts b/test/compat-v041.test.ts index b44750d4f..36c7c357d 100644 --- a/test/compat-v041.test.ts +++ b/test/compat-v041.test.ts @@ -235,7 +235,7 @@ describe('Compat v0.4.1: Config Path Equivalence', () => { it('DEFAULT_CONFIG has expected shape', () => { expect(DEFAULT_CONFIG.version).toBe('1.0.0'); - expect(DEFAULT_CONFIG.models.defaultModel).toBe('claude-sonnet-4.5'); + expect(DEFAULT_CONFIG.models.defaultModel).toBe('claude-sonnet-4.6'); expect(DEFAULT_CONFIG.models.defaultTier).toBe('standard'); expect(DEFAULT_CONFIG.routing.rules.length).toBeGreaterThanOrEqual(1); expect(DEFAULT_CONFIG.casting?.allowlistUniverses).toBeDefined(); @@ -475,7 +475,7 @@ describe('Compat v0.4.1: Model Catalog', () => { }); it('standard fallback chain starts with sonnet', () => { - expect(DEFAULT_FALLBACK_CHAINS.standard[0]).toBe('claude-sonnet-4.5'); + expect(DEFAULT_FALLBACK_CHAINS.standard[0]).toBe('claude-sonnet-4.6'); }); it('fast fallback chain starts with haiku', () => { diff --git a/test/config.test.ts b/test/config.test.ts index 0d5e84e5d..47e8980bd 100644 --- a/test/config.test.ts +++ b/test/config.test.ts @@ -242,7 +242,7 @@ describe('Configuration Loader', () => { describe('DEFAULT_CONFIG', () => { it('should have valid structure', () => { expect(DEFAULT_CONFIG.version).toBe('1.0.0'); - expect(DEFAULT_CONFIG.models.defaultModel).toBe('claude-sonnet-4.5'); + expect(DEFAULT_CONFIG.models.defaultModel).toBe('claude-sonnet-4.6'); expect(DEFAULT_CONFIG.models.defaultTier).toBe('standard'); expect(DEFAULT_CONFIG.models.fallbackChains.premium).toBeInstanceOf(Array); expect(DEFAULT_CONFIG.models.fallbackChains.standard).toBeInstanceOf(Array); diff --git a/test/init.test.ts b/test/init.test.ts index 2b57d981f..824914456 100644 --- a/test/init.test.ts +++ b/test/init.test.ts @@ -82,7 +82,7 @@ describe('Squad Initialization', () => { const configContent = await readFile(result.configPath, 'utf-8'); const parsed = JSON.parse(configContent); expect(parsed.version).toBe('1.0.0'); - expect(parsed.models.defaultModel).toBe('claude-sonnet-4.5'); + expect(parsed.models.defaultModel).toBe('claude-sonnet-4.6'); expect(parsed.routing.rules).toHaveLength(4); }); diff --git a/test/models.test.ts b/test/models.test.ts index 9f87c5e4f..51daee01e 100644 --- a/test/models.test.ts +++ b/test/models.test.ts @@ -76,7 +76,7 @@ describe('DEFAULT_FALLBACK_CHAINS', () => { }); it('starts standard chain with sonnet', () => { - expect(DEFAULT_FALLBACK_CHAINS.standard[0]).toBe('claude-sonnet-4.5'); + expect(DEFAULT_FALLBACK_CHAINS.standard[0]).toBe('claude-sonnet-4.6'); }); it('starts fast chain with haiku', () => {