fix: fail loud instead of silently swapping models on an unresolvable pin - #137
Merged
Conversation
… pin agent()'s model resolution had two stacked gaps: an unresolvable model spec (e.g. a bare aggregator-style id like "moonshotai/kimi-k3" whose vendor segment collides with a real, separately-registered provider name) silently fell back to the session default with only a console.warn, and the resolver itself lacked pi CLI's auth-aware preference for an authenticated raw-id match over an unauthenticated same-named provider. Now an unresolvable model/tier spec throws a clear MODEL_NOT_FOUND error before the subagent session is even created, instead of quietly running against a different (possibly unauthenticated) model. resolveModelSpecWithThinking also gained the missing auth-preference check, cross-verified against pi-coding-agent's own resolveCliModel via a fuzzed property test so future drift between the two is caught immediately. Closes #131.
An explicit model or tier pin that resolves to an unavailable model now throws MODEL_NOT_FOUND naming its source (e.g. which tier, and what it resolved to), matching the existing explicit-model behavior. An untagged agent routed only through the implicit default "medium" tier never asked for that specific model, so it still degrades to the session default when unavailable — but the degrade now fires a run-visible log event instead of being silent, and only once per run. Also strengthens the model-spec parity property test so it actually exercises the auth-preference branch against pi-coding-agent's real resolveCliModel (the previous fuzz domain never triggered it), and updates the workflow-authoring skill references and generated capability facts that still described the old blanket fallback.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
agent({ model })pin, agent-type model, explicittier, or phase/metadata-routed model that can't be resolved now throwsMODEL_NOT_FOUND(recoverable: false) before the subagent session is created, instead of silently running against the session default. Tier failures name their source (tier "big" from model-tiers.json resolves to "…", which is not available). Scripts cantry/catchto degrade on their own. Fixes agent() silently returns null on a bare model pin despite the subagent generating successfully #131.mediumtier still degrades gracefully to the session default when that tier is unavailable — but the fallback is now visible as a once-per-run entry in the run log instead of a console warning.onModelFallbacknarrows to exactly this case (new object signature).vendor/modelid whose vendor segment collides with an unauthenticated provider name resolves to the authenticated aggregator's literal id, matchingresolveCliModel— cross-verified against pi's real resolver with property tests so future drift fails fast.Test plan
npm test— 1160 passing, release gate 0 warningsresolveCliModel