diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index ffc6c36da..3705268bb 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -2,6 +2,10 @@ ## [Unreleased] +### Fixed + +- Fixed unconfigured `pi/smol` and `pi/slow` agent model roles using cloud-priority defaults before the user's configured `modelRoles.default`, which could route local-default setups to authenticated paid providers ([#2336](https://github.com/can1357/oh-my-pi/issues/2336)). + ## [15.11.3] - 2026-06-11 ### Fixed diff --git a/packages/coding-agent/src/config/model-resolver.ts b/packages/coding-agent/src/config/model-resolver.ts index 92164f122..9bb97f655 100644 --- a/packages/coding-agent/src/config/model-resolver.ts +++ b/packages/coding-agent/src/config/model-resolver.ts @@ -633,6 +633,10 @@ function isSessionInheritedAgentPattern(value: string): boolean { return value === DEFAULT_MODEL_ROLE || value === `${PREFIX_MODEL_ROLE}${DEFAULT_MODEL_ROLE}` || value === "pi/task"; } +function shouldInheritDefaultBeforePriority(role: ModelRole): boolean { + return role === "smol" || role === "slow"; +} + function resolveConfiguredRolePattern(value: string, settings?: Settings): string[] | undefined { const normalized = value.trim(); if (!normalized) return undefined; @@ -642,9 +646,13 @@ function resolveConfiguredRolePattern(value: string, settings?: Settings): strin if (!role) return [normalized]; const configured = settings?.getModelRole(role)?.trim(); + const configuredDefault = shouldInheritDefaultBeforePriority(role) ? settings?.getModelRole(DEFAULT_MODEL_ROLE)?.trim() : undefined; const roleDefaults = normalizeModelPatternList(MODEL_PRIO[role as keyof typeof MODEL_PRIO]); - const resolved = configured ? normalizeModelPatternList(configured) : roleDefaults; - if (!resolved || resolved.length === 0) { + const resolved = configured ? normalizeModelPatternList(configured) : normalizeModelPatternList(configuredDefault); + if (resolved.length === 0) { + resolved.push(...roleDefaults); + } + if (resolved.length === 0) { return undefined; } diff --git a/packages/coding-agent/test/model-resolver.test.ts b/packages/coding-agent/test/model-resolver.test.ts index 1a24299e7..cd2db5f2f 100644 --- a/packages/coding-agent/test/model-resolver.test.ts +++ b/packages/coding-agent/test/model-resolver.test.ts @@ -545,6 +545,15 @@ describe("resolveAgentModelPatterns", () => { expect(result).toEqual(["anthropic/claude-sonnet-4-5:high"]); }); + test("uses default for unconfigured smol and slow agent roles before priority defaults", () => { + const settings = Settings.isolated({ + modelRoles: { default: "local/llama" }, + }); + + expect(resolveAgentModelPatterns({ agentModel: "pi/smol", settings })).toEqual(["local/llama"]); + expect(resolveAgentModelPatterns({ agentModel: "pi/slow", settings })).toEqual(["local/llama"]); + }); + test("expands pi/designer to priority defaults", () => { const settings = Settings.isolated({ modelRoles: {