Repository navigation
feat(sdk): central model resolution, GA quality profiles, and HydraFusion opt-in - #2225
Conversation
…ources resolveModel now applies MODEL_RESOLUTION_PRECEDENCE (user-override > config > session > charter > task-auto > default), returns a rationale for every choice, passes a session-picked model through to sub-agent spawns with source `session`, and selects from the tier fallback chain (source `fallback`) when the chosen model is listed in unavailableModels. Task-auto picks now read the tier chain head instead of hard-coding IDs. Coordinator spawn guidance (squad.agent.md) and model-selection-reference are model-ID agnostic: they defer to the resolver precedence, acknowledge model + source + rationale, and keep catalog IDs in a separate appendix. A coordinator contract test enforces the no-model-ID rule. Refs #1720 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 79bd3e85-5096-4dae-a1ef-937c21d2c48e
… and auto sentinel Revision of the central model resolver after review: - The root `resolveModel` export is now a compatible string adapter over the central resolver, so it reads .squad/config.json through the same precedence and no longer returns a literal `auto`. Guidance names the provenance-returning entry point `@bradygaster/squad-sdk/agents`. - AgentLifecycleManager.spawnAgent applies persistent config (agentModelOverrides, defaultModel, economyMode) and records provenance on AgentHandle.modelResolution, OTel span attributes and an agent:milestone `model.resolved` event. - Availability fallback moves forward from the chosen chain position; out-of-chain models search from the head; no remaining candidate sets omitModel. - `auto` (any case/whitespace) is no preference at every layer, including the per-spawn override. - ResolvedModel.rationale stays optional for consumer-built values; resolveModel returns ModelResolution with rationale guaranteed. Refs #1720 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: e022a055-6a4e-4c88-b619-bd46be161840
…llback under cost policy - SpawnAgentOptions gains sessionModel and unavailableModels, forwarded to the central resolver (user-override > config > session > charter > task > default); an exhausted chain omits the model key from the SDK session config. - Explicit over-ceiling cost-policy finalization keeps only chain entries after the chosen model, so availability fallback never moves back toward the head. - Export resolveAgentModel from @bradygaster/squad-sdk/agents as an additive alias of resolveModel; docs, changeset and tests name the literal export. Refs #1720 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8a345356-f72f-4e9d-a28b-678c7c934eaa
An unavailable out-of-catalog pick (e.g. session-selected hydrafusion) bypassed cost-ceiling pruning, so availability fallback could choose a catalog model above config.costPolicy / sessionCostPolicy. Fallback now skips catalog-known candidates above the effective ceiling and omits the model when none remain; available explicit picks still pass through. Refs #1720 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: befc2d3a-18c3-4002-9194-2fbd510375d5
Task-aware selection runs under a quality profile: quality-first (default), balanced or economy (explicit opt-in via session, economyMode or persistent modelProfile). Profiles flow through the central resolver, spawn and the compatibility adapter; explicit overrides and cost ceilings are untouched. availableModels (live runtime list) is authoritative for availability. Catalog, fallback chains and economy map now list only public GA models (docs.github.com supported-models), tiered by Copilot model-picker category. Removed from recommendations: claude-opus-4.7, claude-opus-4.6, claude-sonnet-4.6, claude-sonnet-4.5, gemini-3.1-pro (still passed through when named explicitly). Closes #1598 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: eeb9fa1f-ceee-4184-afcd-5cd32d9d04dc
Add hydrafusion and hydrafusion-max as preview, opt-in catalog entries (premium tier) excluded from every default chain and GA profile, and an opt-in 'hydrafusion' quality profile that sends quality-sensitive tasks to hydrafusion first, then the quality-first premium chain. Scribe and mechanical work stay fast. hydrafusion-max is used only when named explicitly. Implicit in-ceiling replacement never picks a preview model. Docs updated in .squad-templates and synced to mirrors. Closes #2014 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 0a61585a-655c-46db-8ea9-52e83531d7eb
🟠 Impact Analysis — PR #2225Risk tier: 🟠 HIGH 📊 Summary
🎯 Risk Factors
📦 Modules Affectedci-workflows (1 file)
docs (2 files)
root (10 files)
squad-cli (5 files)
squad-sdk (10 files)
templates (4 files)
tests (17 files)
|
🏗️ Architectural Review
Automated architectural review — informational only. |
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 10 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | 3 active Copilot thread(s) resolved (1 outdated skipped) |
| ✅ | CI passing | All checks passing |
Files Changed (49 files, +3576 −745)
| File | +/− |
|---|---|
.changeset/central-model-resolver.md |
+8 −0 |
.changeset/economy-model-fallback.md |
+5 −0 |
.changeset/economy-status-model-ids.md |
+5 −0 |
.changeset/hydrafusion-opt-in.md |
+5 −0 |
.changeset/quality-model-profiles.md |
+9 −0 |
.github/agents/squad.agent.md |
+7 −5 |
.squad-templates/model-selection-reference.md |
+108 −50 |
.squad-templates/skills/economy-mode/SKILL.md |
+13 −13 |
.squad-templates/skills/model-selection/SKILL.md |
+38 −15 |
.squad-templates/squad.agent.md |
+7 −5 |
README.md |
+2 −0 |
docs/src/content/docs/features/model-selection.md |
+127 −47 |
docs/src/content/docs/features/vscode.md |
+3 −3 |
packages/squad-cli/src/cli/commands/economy.ts |
+4 −4 |
packages/squad-cli/templates/model-selection-reference.md |
+108 −50 |
packages/squad-cli/templates/skills/economy-mode/SKILL.md |
+13 −13 |
packages/squad-cli/templates/skills/model-selection/SKILL.md |
+38 −15 |
packages/squad-cli/templates/squad.agent.md.template |
+7 −5 |
packages/squad-sdk/src/agents/index.ts |
+14 −0 |
packages/squad-sdk/src/agents/lifecycle.ts |
+190 −9 |
packages/squad-sdk/src/agents/model-selector.ts |
+496 −78 |
packages/squad-sdk/src/config/models.ts |
+289 −126 |
packages/squad-sdk/src/config/schema.ts |
+3 −3 |
packages/squad-sdk/src/runtime/constants.ts |
+18 −10 |
packages/squad-sdk/templates/model-selection-reference.md |
+108 −50 |
packages/squad-sdk/templates/skills/economy-mode/SKILL.md |
+13 −13 |
packages/squad-sdk/templates/skills/model-selection/SKILL.md |
+38 −15 |
packages/squad-sdk/templates/squad.agent.md.template |
+7 −5 |
templates/model-selection-reference.md |
+108 −50 |
templates/skills/economy-mode/SKILL.md |
+13 −13 |
templates/skills/model-selection/SKILL.md |
+38 −15 |
templates/squad.agent.md.template |
+7 −5 |
test/agents.test.ts |
+30 −27 |
test/catalog-refresh.test.ts |
+28 −17 |
test/compat-v041.test.ts |
+11 −11 |
test/config-integration.test.ts |
+1 −1 |
test/config-schema.test.ts |
+1 −1 |
test/coordinator.test.ts |
+100 −0 |
test/economy-mode.test.ts |
+80 −20 |
test/feature-parity.test.ts |
+1 −1 |
test/integration.test.ts |
+7 −3 |
test/lifecycle.test.ts |
+168 −3 |
test/model-fallback.test.ts |
+149 −7 |
test/model-hydrafusion.test.ts |
+405 −0 |
test/model-preference.test.ts |
+374 −2 |
test/model-quality-profiles.test.ts |
+329 −0 |
test/model-selector-policy.test.ts |
+5 −5 |
test/models.test.ts |
+32 −24 |
test/telemetry-auto-wiring.test.ts |
+6 −6 |
Total: +3576 −745
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
There was a problem hiding this comment.
🟡 Changes recommended
Default preview recommendations, economy controls, and resolver-to-executor fallback handling retain correctness issues.
4 open findings
What changed in this PR
Centralizes Squad SDK model selection to respect user preferences, default to quality-first recommendations, and support explicit HydraFusion opt-in.
Changes:
- Adds source-aware resolution, session inheritance, availability handling, and spawn provenance.
- Refreshes model catalogs and introduces quality profiles with preview opt-in.
- Synchronizes coordinator guidance and expands regression coverage.
| File | Description |
|---|---|
| test/telemetry-auto-wiring.test.ts | Updates catalog pricing expectations. |
| test/models.test.ts | Refreshes registry and preview assertions. |
| test/model-selector-policy.test.ts | Updates cost-ceiling expectations. |
| test/model-quality-profiles.test.ts | Covers profiles and live availability. |
| test/model-preference.test.ts | Covers precedence, provenance, and fallback. |
| test/model-hydrafusion.test.ts | Covers preview opt-in and task gating. |
| test/model-fallback.test.ts | Updates fallback-chain expectations. |
| test/lifecycle.test.ts | Covers preferences and spawn provenance. |
| test/integration.test.ts | Updates quality-first pipeline expectations. |
| test/feature-parity.test.ts | Refreshes registry lookup. |
| test/economy-mode.test.ts | Updates economy mappings and defaults. |
| test/coordinator.test.ts | Adds spawn-guidance contract checks. |
| test/config-schema.test.ts | Updates standard-tier expectation. |
| test/config-integration.test.ts | Refreshes model availability assertion. |
| test/compat-v041.test.ts | Updates catalog compatibility expectations. |
| test/catalog-refresh.test.ts | Refreshes catalog membership and ordering. |
| test/agents.test.ts | Updates task-aware selection expectations. |
| templates/squad.agent.md.template | Mirrors coordinator resolution guidance. |
| templates/skills/model-selection/SKILL.md | Mirrors profile and preview guidance. |
| templates/skills/economy-mode/SKILL.md | Mirrors economy-profile guidance. |
| templates/model-selection-reference.md | Mirrors model-selection reference. |
| packages/squad-sdk/templates/squad.agent.md.template | Ships updated coordinator guidance. |
| packages/squad-sdk/templates/skills/model-selection/SKILL.md | Ships profile and preview guidance. |
| packages/squad-sdk/templates/skills/economy-mode/SKILL.md | Ships economy-profile guidance. |
| packages/squad-sdk/templates/model-selection-reference.md | Ships updated selection reference. |
| packages/squad-sdk/src/runtime/constants.ts | Refreshes default fallback chains. |
| packages/squad-sdk/src/config/schema.ts | Aligns configured tier chains. |
| packages/squad-sdk/src/agents/lifecycle.ts | Wires preferences and resolution provenance. |
| packages/squad-sdk/src/agents/index.ts | Exports resolver helpers and types. |
| packages/squad-cli/templates/squad.agent.md.template | Ships updated coordinator guidance. |
| packages/squad-cli/templates/skills/model-selection/SKILL.md | Ships profile and preview guidance. |
| packages/squad-cli/templates/skills/economy-mode/SKILL.md | Ships economy-profile guidance. |
| packages/squad-cli/templates/model-selection-reference.md | Ships updated selection reference. |
| .squad-templates/squad.agent.md | Defines coordinator precedence and acknowledgments. |
| .squad-templates/skills/model-selection/SKILL.md | Documents profiles and HydraFusion opt-in. |
| .squad-templates/skills/economy-mode/SKILL.md | Documents economy-profile behavior. |
| .squad-templates/model-selection-reference.md | Defines selection rules and catalog appendix. |
| .github/agents/squad.agent.md | Updates active coordinator guidance. |
| .changeset/quality-model-profiles.md | Records profile and catalog changes. |
| .changeset/hydrafusion-opt-in.md | Records preview opt-in support. |
| .changeset/central-model-resolver.md | Records resolver and lifecycle changes. |
Review effort: Balanced
|
This is awesome! Well done team! |
|
@bradygaster we need the docs updated before this merges. The public page Could you add the following?
Once the docs land we can review this for merge. |
|
HydraFusion! Love it! Thank you! Perfect pairing with Squad! |
tamirdresher
left a comment
There was a problem hiding this comment.
Went through this again. The overall direction looks good to me, but I don't think we can merge yet. The four comments from the Copilot reviewer are real bugs and are still open, so please take care of those first:
- model-selector.ts:396 When everything is unavailable we can still send an empty model id into ModelFallbackExecutor.execute(), since it never looks at omitModel.
- model-selector.ts:211 The fallbackChain we return isn't filtered by availability and isn't trimmed to where the selected model sits.
- models.ts:427 getRecommendedModels() doesn't check preview, so HydraFusion shows up in normal research and architecture recommendations. That breaks the whole "opt in only" promise.
- models.ts:775 With modelProfile set to "economy", squad economy says it's off and squad economy off doesn't actually turn it off. Those two settings need to agree.
Also the branch is behind dev, so it needs an update.
…on opt-in (#2225) Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5958f622-3345-44b2-b0ac-f0394b732686
…, preview recs, economy profile) - Normalize resolveModel fallbackChain: availability-filtered and forward-only from the selected model; out-of-chain picks keep head-first fallback. - ModelFallbackExecutor.execute handles omitModel via an optional platformDefault callback; never calls fn with an empty model id. - ModelRegistry.getRecommendedModels excludes preview entries. - readEconomyMode recognizes modelProfile 'economy'; economy off removes it. - AgentLifecycleManager: a profile-picked preview model that is unavailable or rejected by createSession falls forward to the premium chain with a single user notice instead of failing the spawn. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5958f622-3345-44b2-b0ac-f0394b732686
Part of #2225 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5958f622-3345-44b2-b0ac-f0394b732686
tamirdresher
left a comment
There was a problem hiding this comment.
Thanks for turning this around so fast. Went through 26054dd and 097cb9f and all four findings plus the HydraFusion unavailable case look good to me. Docs read well too. Approving.
Two small things, neither blocks the merge, fine as a follow up:
- readEconomyMode returns true for a config with "economyMode": false and "modelProfile": "economy", but the resolver (models.ts:1700) and the docs treat an explicit false as cancelling the economy profile. So squad economy would say on while spawns aren't actually in economy. Only happens with a hand edited config since squad economy off deletes the key, but it'd be nice if they agreed.
- The createSession retry in lifecycle.ts catches any error, so a network blip or auth error on a HydraFusion spawn also gets treated as "not available" and quietly falls to Opus. Might be worth narrowing that to model rejection errors if the SDK gives us a way to tell.
Also the HydraFusion link in model-selection.md points to the Sep 30 changelog. The Oct 14 one is the one that introduced Max: https://github.blog/changelog/2026-10-14-hydrafusion-updates-and-new-max-option/
Please squash when merging.

What
Adds a shared, source-aware agent model resolver, refreshes recommendations around public GA models, and adds explicit HydraFusion opt-in. The default profile is
quality-first;balanced,economy, andhydrafusionrequire opt-in. Includes synchronized coordinator guidance, template documentation, and three SDK changesets. The combined branch contains the sequentially reviewed Units A, B, and C (43 files, no file deletions).Why
Squad should respect the model a customer explicitly selects in Copilot, recommend current customer-facing GA models by default, and let opted-in users benefit from HydraFusion without making preview models implicit defaults.
Closes #1720
Closes #1598
Closes #2014
How
resolveAgentModelfrom/agentsas an alias of the source-awareresolveModel, preserving the legacy root adapter.modelkey.hydrafusionandhydrafusion-maxas preview. Thehydrafusionprofile selects HydraFusion for architecture, research, verification, review, security, and design; other tasks keep quality-first selection. HydraFusion Max is never automatically recommended and requires a named selection.Review considerations: catalog-driven CLI model listing now includes the two preview IDs. Visual tasks do not select HydraFusion automatically because its vision capability is undocumented.
sessionModelis supplied throughSpawnAgentOptions, notLifecycleManagerConfig. The generated charter wording inroles/index.tsremains outside this scope.npx changeset add/.changeset/*.md, directCHANGELOG.mdentry for maintainers, orskip-changeloglabel for no user-facing changes)PR Readiness Checklist
Branch & Commit
dev(notmain)dev(git fetch upstream && git rebase upstream/dev)git diff --cached --stat)The working tree is clean, the approved cumulative diff was inspected, and a live
git fetch origin devconfirmed no commits onorigin/devare missing from this branch. The six implementation/repair commits are retained for review provenance; they have not been rewritten.Build & Test
npm run buildpassesnpm testpasses (all tests green)npm run lintpasses (type check clean)npm run lint:eslintpassesValidation evidence:
SKIP_BUILD_BUMP=1 npm run build: passed at final HEAD8c08b7fa, with no generated drift.npm run lint: passed in the Unit C worktree at8c08b7fa(SDK and CLI typechecks).npx vitest run test/model-hydrafusion.test.ts test/model-quality-profiles.test.ts test/model-preference.test.ts test/lifecycle.test.ts test/models.test.ts test/catalog-refresh.test.ts test/model-fallback.test.ts test/model-selector-policy.test.ts test/coordinator.test.ts test/template-sync.test.ts: independently rerun at final HEAD; 10 files and 829 tests passed.npm run lint:eslint: not run; the root package has no such script.Environment: the local Microsoft npm proxy lacks
playwright-core@1.64.0and@types/node@26.6.5. Unit worktrees used temporarily relaxed manifests for dependency installation, then restored manifests byte-for-byte. No manifest or lockfile workaround is committed. Final verification used Unit C's populated worktree on the exact same HEAD rather than modifying dependencies in the coordinator worktree.Changeset
npx changeset add(ifpackages/squad-sdk/src/orpackages/squad-cli/src/changed)CHANGELOG.mdentry (maintainers only — write-protected for external contributors)skip-changeloglabel applied (if no user-facing changes)Changeset files are included:
central-model-resolver.md,quality-model-profiles.md, andhydrafusion-opt-in.md. The direct-CHANGELOG and skip-changelog alternatives are not used.Docs
Updated the canonical model-selection reference, model-selection/economy skills, coordinator task-auto wording, and required mirrors. README and site feature-page updates are not included.
Exports
N/A: no new module/subpath. The existing
/agentsbarrel exposes the central resolver and related types.Breaking Changes
Selection defaults intentionally change from cost-first to quality-first; users can explicitly opt into
balancedoreconomy. Removed stale catalog IDs are no longer recommended, and cost estimation for an uncataloged ID returns zero. Explicit custom IDs retain resolver passthrough where available. An unavailable explicit HydraFusion selection under a versatile ceiling now omitsmodel, because the forward-only premium fallback chain has no in-ceiling candidate; it does not bypass the ceiling. No existing resolver export was renamed.Manual Copilot app/CLI/VS Code verification remains pending: verify profile-based HydraFusion selection with a fast Scribe, session-model inheritance, fallback without preview access, explicit-only HydraFusion Max, and VS Code's single-session-model behavior.
Waivers
Requested, not approved: full-suite green due to reproduced baseline/environment failures; the nonexistent ESLint script; README/site feature-page updates in favor of the updated model-selection documentation; and retaining the review-provenance commit sequence. Lead or Quality approval in PR comments is required before merge for any applicable required item. No waiver approval is claimed.