Fix model picker alias/provider scoped options#75267
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Keep open. The underlying provider-scoped model-picker bug still exists on current main and this PR is useful, but it is not merge-ready because the branch conflicts with main, lacks real behavior proof, and the proposed fix introduces source-visible edge cases around fallback scoping and invalid initial selection. Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review. So I’m closing this here because the remaining work is already tracked in the canonical issue. Review detailsBest possible solution: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review. Do we have a high-confidence way to reproduce the issue? Yes, by source inspection. Current main filters to the preferred provider only when matching rows exist, but then still appends the configured model supplement unconditionally when it was not seen. Is this the best way to solve the issue? No, not as currently written. The fix belongs in Security review: Security review cleared: The diff only changes TypeScript model-picker logic and tests; no dependency, workflow, secret, permission, package, or code-download surface was introduced. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 66880a5d736c. |
There was a problem hiding this comment.
Pull request overview
This PR tightens provider-scoped model picker behavior so that hidden/invalid alias+provider pairs can’t be returned as the default selection, and adds regression tests around provider scoping and allowlist option validity.
Changes:
- Hide the “current (not in catalog)” configured model supplement when it doesn’t match the preferred provider scope.
- Ensure
initialValuealways points at a displayed option (fallback to a visible entry). - Add regression coverage for cross-provider alias leakage and allowlist option validation in provider-scoped pickers.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
src/flows/model-picker.ts |
Adjusts option/supplement visibility and clamps initialValue to displayed options for provider-scoped default model selection. |
src/commands/model-picker.test.ts |
Adds regression tests for provider-scoped default picker and allowlist picker behavior. |
| if ( | ||
| configuredKey && | ||
| !seen.has(configuredKey) && | ||
| (!preferredProvider || matchesPreferredProvider?.(resolved.provider)) | ||
| ) { | ||
| options.push({ | ||
| value: configuredKey, | ||
| label: configuredLabel, | ||
| hint: "current (not in catalog)", | ||
| }); | ||
| seen.add(configuredKey); |
There was a problem hiding this comment.
The configured “current (not in catalog)” supplement is now hidden whenever preferredProvider is set and the current resolved provider doesn’t match. This can also hide the supplement in cases where the picker isn’t actually scoped (i.e. hasPreferredProvider is false because no catalog entries match the preferred provider), which makes the current configured model unselectable when it’s not in the catalog (especially when allowKeep: false). Consider gating this hiding behavior on hasPreferredProvider (only enforce scope when there are in-scope options to pick).
| if (initialValue && !optionValues.has(initialValue)) { | ||
| initialValue = options[0]?.value; | ||
| } |
There was a problem hiding this comment.
initialValue fallback currently uses options[0]?.value when the computed initialValue isn’t displayed. Since action options (e.g. “Enter model manually” / provider setup entries / “Keep current”) are prepended before model rows, this can default the selection to a non-model action even when model options exist later. Also, with provider-scoped hiding of the configured supplement plus auth-filtering, it’s possible for options to be empty here, which will pass an empty options list into the Clack select/autocomplete prompt (likely throwing). Suggestion: if initialValue is invalid, prefer the first model option (e.g. a value that parses via splitModelKey), and if there are no options at all, fall back to promptManualModel (or otherwise avoid calling prompter.select with options.length === 0).
| if (initialValue && !optionValues.has(initialValue)) { | |
| initialValue = options[0]?.value; | |
| } | |
| const firstModelOptionValue = options.find((option) => seen.has(option.value))?.value; | |
| if (initialValue && !optionValues.has(initialValue)) { | |
| initialValue = firstModelOptionValue; | |
| } | |
| if (options.length === 0) { | |
| return promptManualModel({ | |
| prompter: params.prompter, | |
| allowBlank: false, | |
| initialValue: configuredRaw || resolvedKey || undefined, | |
| }); | |
| } |
|
This pull request has been automatically marked as stale due to inactivity. |
|
This pull request has been automatically marked as stale due to inactivity. |
|
ClawSweeper applied the proposed close for this PR.
|
Summary
Tests
Linear: AI-594