feat(site): surface reasoning effort configuration on the models page - #26976
Conversation
4b151ef to
fef1b86
Compare
4968c7e to
15d4c72
Compare
fef1b86 to
096c142
Compare
15d4c72 to
228a7db
Compare
096c142 to
148d505
Compare
228a7db to
d39150f
Compare
148d505 to
c11b76d
Compare
d39150f to
355f182
Compare
c11b76d to
03e26de
Compare
355f182 to
3d36549
Compare
03e26de to
ce60d2e
Compare
3d36549 to
f677efc
Compare
ce60d2e to
3fb0e55
Compare
f677efc to
4b77a03
Compare
3fb0e55 to
0ea0c51
Compare
4b77a03 to
c485ab1
Compare
0ea0c51 to
1e573ac
Compare
c485ab1 to
a1bbe9e
Compare
1e573ac to
686a707
Compare
a1bbe9e to
a1ccef1
Compare
686a707 to
d784fbf
Compare
a1ccef1 to
8f4025c
Compare
d784fbf to
ee3f120
Compare
|
/coder-agents-review |
|
Chat: Review posted | View chat Review historydeep-review v0.9.0 | Round 3 | Last posted: Round 3, 10 findings (6 P3, 3 P4, 1 Nit), APPROVE. Review Finding inventoryFindings
Contested and acknowledgedCRF-1 (P3, ModelConfigFields.tsx:725) - "Xhigh" display label
CRF-2 (P3, ModelConfigFields.tsx:669) - PR description mismatch
CRF-8 (P4, ModelForm.stories.tsx:221) - No story for "Not set" clear path
Round logRound 1Panel. Netero clean. 5 P3 posted, 4 P4 (1 dropped, 3 posted). Reviewed against 8f4025c..ee3f120. Round 2Churn guard: PROCEED. 5 addressed, 1 acknowledged, 2 contested (CRF-1, CRF-8). Panel: 9 reviewers. Fixes verified. CRF-1 closed (3/5 accept). CRF-8 closed (5/5 accept). 1 new P3 (CRF-10), 1 new Nit (CRF-11). Reviewed against 8f4025c..3136441. Round 3Churn guard: PROCEED. 2 addressed (CRF-10, CRF-11). Panel: 4 reviewers. CRF-10 and CRF-11 fixes verified. 2 new Gon P2 findings dropped (comments are functional after 3 rounds of improvements). No open findings. Reviewed against 8f4025c..3485634. About deep-reviewCRF = Coder Review Finding (P0-P4, Nit, Note)
|
There was a problem hiding this comment.
Clean, focused PR. The form wiring is correct, the Storybook test is genuine (end-to-end from click to payload), and the filter-then-render pattern matches the codebase conventions.
5 P3 findings, 3 P4 findings, no blockers. The biggest themes: the "Xhigh" label looks like a typo now that it's front and center in a dropdown (7 reviewers flagged this), the PR description claims provider-scoped filtering that the code doesn't implement, and the inline Select rendering duplicates SelectField for a single-string difference that a prop could solve.
"The only non-obvious content is the placement guidance." Gon, on the comments
🤖 This review was automatically generated with Coder Agents.
| <SelectItem value={unsetSelectValue}>Not set</SelectItem> | ||
| {(field.enum ?? []).map((option) => ( | ||
| <SelectItem key={option} value={option}> | ||
| {capitalize(option)} |
There was a problem hiding this comment.
P3 [CRF-1] capitalize("xhigh") renders "Xhigh" in the dropdown. Every sibling label (None, Minimal, Low, Medium, High, Max) reads as a natural word. "Xhigh" looks like a typo or internal codename to an admin configuring effort bounds. (Leorio P3, Hisoka P3, Luffy P3, Pariston P3, Chopper Nit)
This PR promotes these labels from buried text inputs in Advanced to a prominent always-visible dropdown. A small label map fixes it:
const effortDisplayName: Record<string, string> = { xhigh: "Extra High" };
// in the option rendering:
{effortDisplayName[option] ?? capitalize(option)}The underlying enum value stays "xhigh". Only the UI label changes.
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-1 intentionally unchanged. This was already discussed on PR26974, and we are keeping Xhigh for this stack.
There was a problem hiding this comment.
Panel closed (R2, 3/5 accept). Kite, Pariston, and Mafu-san accepted the defense: the decision was made by a human on the base PR (#26974). The consequence is cosmetic and does not cause misconfiguration.
🤖
| * Kept out of the Advanced section so admins can configure effort bounds | ||
| * without expanding anything. | ||
| */ | ||
| export const ReasoningEffortConfigFields: FC<ModelConfigFieldsProps> = ({ |
There was a problem hiding this comment.
P3 [CRF-2] The PR description says the selects are "limited to the selected provider's supported effort set, hidden for providers without reasoning effort support." Neither is implemented. provider is accepted via ModelConfigFieldsProps but never destructured or read. The fields come from getVisibleGeneralFields(), which is provider-independent. The selects render unconditionally for all providers with the full 7-value enum. (Kite P3, Mafu-san P2, Pariston Nit)
The code is consistent with the architecture: PricingModelConfigFields and GeneralModelConfigFields also ignore provider because general fields are provider-independent by design. No code change needed; the PR description should be corrected to match the actual behavior.
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-2 fixed. The PR body now describes the provider-independent behavior instead of claiming provider-limited or hidden fields.
There was a problem hiding this comment.
Verified fixed. PR description now describes provider-independent behavior.
🤖
| ); | ||
| }; | ||
|
|
||
| /** |
There was a problem hiding this comment.
P3 [CRF-3] Five comments in this PR restate what the function name, code body, or call site already shows. Each is independently small, but the pattern adds noise. (Gon)
Locations and suggested rewrites:
- Line 53 (
isReasoningEffortFieldJSDoc): delete. The name and body say it. - Line 225 (story comment):
// No section expansion needed; effort fields are in the top grid. - Lines 663-668 (this JSDoc):
/** Reasoning effort selects, placed outside Advanced so admins see them without expanding. */ - Lines 689-692 (inline comment):
// Inline select because SelectField's "Default" unset label clashes with "Default Reasoning Effort". - Line 747 (GeneralModelConfigFields JSDoc):
Reasoning effort fields are excluded; see ReasoningEffortConfigFields.
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-3 fixed. The comments were trimmed to keep only the useful context.
There was a problem hiding this comment.
Verified fixed. Comments trimmed to keep only placement context and cross-references.
🤖
| // unset choice can read "Not set": next to a field named | ||
| // "Default Reasoning Effort", the generic "Default" label | ||
| // would be ambiguous. | ||
| return ( |
There was a problem hiding this comment.
P3 [CRF-4] This 44-line inline select rendering (lines 693-736) is structurally identical to SelectField (lines 241-299) in the same file. The only behavioral difference is the unset label: "Not set" vs "Default". The comment at line 689 documents the reason, and the reason is solid, but the fix is a prop, not a copy. (Robin P3, Zoro P3)
Add a placeholderLabel prop to SelectField:
const SelectField: FC<
FieldRenderContext & {
// ... existing props
placeholderLabel?: string; // defaults to "Default"
}
> = ({ ..., placeholderLabel = "Default" }) => {Then ReasoningEffortConfigFields calls SelectField with placeholderLabel="Not set". ~12 lines vs ~70. Future changes to SelectField (styling, aria, error rendering) propagate automatically.
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-4 fixed. SelectField now supports a placeholderLabel, and the reasoning effort fields reuse it with Not set.
There was a problem hiding this comment.
Verified fixed. SelectField gained placeholderLabel prop; ReasoningEffortConfigFields delegates with "Not set". No duplication remains.
🤖
| "Max", | ||
| ]) { | ||
| await expect( | ||
| screen.getByRole("option", { name: option }), |
There was a problem hiding this comment.
P3 [CRF-5] After userEvent.click(defaultSelect), options are queried synchronously with screen.getByRole("option", ...) (line 250). After userEvent.click(maxSelect), the option is queried asynchronously with await screen.findByRole("option", ...) (line 256). Both interactions follow the same pattern: click a Radix SelectTrigger, then query portal content. (Komugi)
This works today because React 18 commits discrete event state updates synchronously and createPortal renders within the same commit. But the inconsistency within a single test is a rough edge: a React or Radix update that changes portal commit timing would break getByRole while findByRole survives. Unify on findByRole for both dropdowns.
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-5 fixed. The story now uses async option lookup for both dropdown interactions.
There was a problem hiding this comment.
Verified fixed. Both dropdowns now use findByRole consistently.
🤖
|
|
||
| // The effort selects sit in the always-visible top grid; no | ||
| // collapsible section is expanded in this story. | ||
| const defaultSelect = canvas.getByRole("combobox", { |
There was a problem hiding this comment.
P4 [CRF-7] The selects render with placeholder="Not set" and no initial value. The test immediately queries for visibility and interacts. One await expect(defaultSelect).toHaveTextContent("Not set") before interaction would catch an unexpected default. (Bisky)
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-7 fixed. The story now asserts both reasoning effort selects initially show Not set.
There was a problem hiding this comment.
Verified fixed. Both selects assert toHaveTextContent("Not set") before interaction.
🤖
| }, | ||
| }; | ||
|
|
||
| export const ReasoningEffortVisibleWithoutExpanding: Story = { |
There was a problem hiding this comment.
P4 [CRF-8] No story exercises selecting a value, clearing it back to "Not set," and confirming the payload omits reasoning_effort. The unsetSelectValue -> "" mapping is unit-tested in modelConfigFormLogic.test.ts, but the rendering round-trip is not. (Bisky)
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-8 intentionally skipped because unit coverage already verifies the omitted payload behavior for unset reasoning effort.
There was a problem hiding this comment.
Panel closed (R2, 5/5 accept). Bisky traced the data path end-to-end: SelectField onValueChange maps unsetSelectValue to "", buildModelConfigFromForm treats "" as unset, unit test at modelConfigFormLogic.test.ts:505 confirms reasoning_effort is undefined. The remaining gap is Radix component behavior, not application logic.
🤖
| ))} | ||
| </SelectContent> | ||
| </Select> | ||
| {fieldError && ( |
There was a problem hiding this comment.
P4 [CRF-9] No story verifies the validation error message renders in the DOM. The default > max validation is well-tested in modelConfigFormLogic.test.ts, but the {fieldError && (<p>...</p>)} rendering path at line 730 has no visual test. (Bisky)
🤖
There was a problem hiding this comment.
🤖 Generated by Coder Agents on behalf of @DanielleMaywood.
CRF-9 fixed. Added a Storybook validation story asserting the rendered default > max error message.
There was a problem hiding this comment.
Verified fixed. ReasoningEffortValidationError story sets default=High, max=Low and asserts the error message renders.
🤖
ee3f120 to
3136441
Compare
|
/coder-agents-review |
There was a problem hiding this comment.
All R1 findings addressed or closed. Fixes verified by the panel. Nice class fix on CRF-4: placeholderLabel prop is the right solution.
Contested findings resolved: CRF-1 (Xhigh label, 3/5 accepted the prior-PR decision) and CRF-8 (clear-path story, 5/5 accepted the unit-test coverage defense).
1 new P3 from the en-dash fix, 1 Nit. The en-dash removal was correct, but the replacement for negative-range placeholders needs a different separator.
"I tried to build a case against this and couldn't." Pariston, on the overall design
🤖 This review was automatically generated with Coder Agents.
| frequency_penalty: "-2.0–2.0", | ||
| temperature: "0.0-2.0", | ||
| top_p: "0.0-1.0", | ||
| presence_penalty: "-2.0-2.0", |
There was a problem hiding this comment.
P3 [CRF-10] The en-dash removal was correct (project bans U+2013), but "-2.0-2.0" has three consecutive hyphens with no visual distinction between the minus sign and the range separator. temperature: "0.0-2.0" is unambiguous because neither bound is negative. (Hisoka P3, Gon P3)
Fix: use a word separator for negative ranges:
presence_penalty: "-2.0 to 2.0",
frequency_penalty: "-2.0 to 2.0",Or apply uniformly: "0.0 to 2.0", "0.0 to 1.0", "-2.0 to 2.0", "-2.0 to 2.0".
🤖
There was a problem hiding this comment.
Coder Agents generated: Fixed in 3485634. The range placeholders now use unambiguous word separators uniformly: 0.0 to 2.0, 0.0 to 1.0, and -2.0 to 2.0.
There was a problem hiding this comment.
Verified fixed in 34856347b313. All four placeholders now use unambiguous "to" separators.
🤖
| play: async ({ canvasElement, args }) => { | ||
| const canvas = within(canvasElement); | ||
|
|
||
| // No section expansion needed; effort fields are in the top grid. |
There was a problem hiding this comment.
Nit [CRF-11] The CRF-3 fix was a genuine improvement. Three residual trims worth considering: (Gon)
- Line 225 (this comment): the story name
ReasoningEffortVisibleWithoutExpandingalready communicates that no expansion is needed. Delete. - ModelConfigFields.tsx:664:
"Reasoning effort selects"restates the component name. Trim to:/** Outside Advanced so admins see effort fields without expanding. */ - ModelConfigFields.tsx:701:
"General model config fields shown under Advanced"is visible from context. Trim to:/** For reasoning effort see ReasoningEffortConfigFields. */
🤖
There was a problem hiding this comment.
Coder Agents generated: Fixed in 3485634. Trimmed the story comment and shortened the reasoning effort comments.
There was a problem hiding this comment.
Verified fixed in 34856347b313. Story comment deleted, doc comments shortened.
🤖
3136441 to
3485634
Compare
|
/coder-agents-review |
There was a problem hiding this comment.
All findings resolved across 3 rounds. CRF-10 (ambiguous placeholders) fixed with uniform "to" separators. CRF-11 (comment trimming) addressed. Clean code, proportional scope, genuine tests.
CI failures (gen, lint, required) are not from this diff. The changed files compile and lint cleanly.
"The agent grepped for the class, not the instance." Mafu-san, on the CRF-10 fix
🤖 This review was automatically generated with Coder Agents.
e737c0a
into
dm/reasoning-effort-1-model-config
Documentation CheckUpdates Needed
Automated review via Coder Agents |
Adds "Default reasoning effort" and "Max reasoning effort" selects to the model form on the deployment Models page, rendered in the always-visible top section (not under the collapsed Advanced section).
The selects are schema-driven from the generated general model options and use the global effort scale through provider-independent model config. They are validated as
default <= max. Includes a Storybook play test asserting the fields are visible without expanding any section and submit asmodel_config.reasoning_effort.Part of the reasoning effort stack (base: #26974).
🤖 Generated by Coder Agents on behalf of @DanielleMaywood