fix: code reviewer config — model dropdown, and default to your AI provider - #5990
Merged
Conversation
…ovider Two fixes to the Code Review Defaults panel (Settings › Code Reviewers) and the reviewer chain behind it. **Model is a dropdown, not a text box.** Every model-taking reviewer with a resolved catalog now renders a `<select>` of its ids. CLI reviewers keep the ability to name an id no catalog can enumerate (an Ollama-backed `claude`, a Bedrock-form id) through a trailing "Custom…" entry that swaps the cell for a free-text input; leaving that field empty returns it to the dropdown. A probed local backend stays a closed list — its ids came from the running daemon — and a reviewer whose catalog resolved empty still starts as free text rather than a dead select. **The unconfigured default follows your default AI provider.** An install that has never opened the panel used to review with GitHub Copilot, which needs a subscription it may not have and ignores the agent the user already chose. The fallback now derives from the active provider — its reviewer slug, its default model, its reasoning effort — with `copilot` kept only as the last resort for a provider that maps to no reviewer at all (a hosted API provider, or none set). A saved chain is untouched, a stored per-reviewer pin still wins over the derived one, a `*-configured-default` sentinel is never pinned as a model, and an effort outside the reviewer's own ladder is dropped rather than clamped. Claude-Session: https://claude.ai/code/session_016N4hdoetFHnLbmoUi2VqfR
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
Two bugs in the Code Review Defaults panel (Settings › Code Reviewers) and the reviewer chain behind it.
1. The Model cell is a dropdown, not a text box
Every model-taking reviewer with a resolved catalog now renders a
<select>of its ids, the same way the Effort column already worked.CLI reviewers keep the ability to name an id no catalog can enumerate — an Ollama-backed
claude, a Bedrock-form id — through a trailing Custom… entry that swaps the cell for a free-text input with the catalog offered as a<datalist>. Leaving that input empty returns the cell to the dropdown (on blur, not on an empty keystroke, so clearing the field to retype doesn't swap the control out from under the cursor).Two cases deliberately still start as free text:
A probed local backend (ollama/lmstudio) keeps its closed select — those ids came from the running daemon, so one it doesn't list isn't installed.
The
Custom…sentinel is[custom], chosen so it can never be confused for a pin:sanitizeReviewerModelInputstrips[/]as the user types and the server'sREVIEWER_MODEL_FORBIDDEN_RErejects them, so no build could have persisted it.2. The unconfigured default follows your default AI provider
An install that had never opened the panel reviewed with GitHub Copilot — which needs a subscription it may not have, and ignores the agent the user already told PortOS to run.
The fallback now derives from the active AI provider: its reviewer slug, its
defaultModel, and its reasoning effort. New inserver/lib/reviewerConfig.js:reviewerForProvider(provider)— local-LLM reviewers matched by provider id (ollama/lmstudio/mtplx, which spawn no binary), CLI reviewers matched by the binary the provider spawns, looked up through the existingREVIEWER_CLI_BINARIEStable so the slug↔executable mapping (antigravity→agy) stays in one place.codeReviewDefaultsFromProvider(provider)— the reviewer plus its model and effort, ornullwhen the provider maps to no reviewer.Guardrails, all covered by tests:
<reviewer>Model/<reviewer>Effortpin still wins over the derived one, per key;*-configured-defaultsentinel is dropped rather than pinned as a model (it means "whatever the CLI is configured for", not an id--modelcould take);agyreally does reject--effort max);copilotremains the last resort, for a hosted API provider that maps to no reviewer, or no provider at all.getCodeReviewDefaultsmemoizes only the settings-derived answer, whichsettings:updatedfully invalidates. The provider-derived one is re-resolved per call — switching the active provider fires no settings event, and the toolkit already caches the provider list in memory, so this costs no disk I/O.Test plan
server/lib/reviewerConfig.test.js— CLI-binary and local-id mapping, locally-served wrappers, providers that map to nothing; sentinel-model and out-of-ladder-effort drops.server/services/codeReview.test.js— derive from the active provider; leave a configured chain alone; stored pin beats derived; copilot kept for an unmappable provider;getCodeReviewDefaultsend to end.client/src/components/cos/ReviewerPicker.test.jsx— CLI reviewer renders a dropdown;Custom…swaps in the input and stores nothing; no escape offered to a probed backend; blur-with-nothing-pinned reverts; the input survives a clear-and-retype; an out-of-catalog pin stays editable.npm run buildclean.Reviewed locally by
claude(--review-with claude[claude-sonnet-5]~opt~max=1~effort=low) — clean, no findings.https://claude.ai/code/session_016N4hdoetFHnLbmoUi2VqfR