Skip to content

fix(site): remember reasoning effort per model on new chat#27457

Merged
DanielleMaywood merged 2 commits into
mainfrom
danielle/codagt-799-store-latest-selected-effort-level-for-each-model
Jul 23, 2026
Merged

fix(site): remember reasoning effort per model on new chat#27457
DanielleMaywood merged 2 commits into
mainfrom
danielle/codagt-799-store-latest-selected-effort-level-for-each-model

Conversation

@DanielleMaywood

Copy link
Copy Markdown
Contributor

When we split the reasoning (thinking) effort selector out of the model config, the New chat page never remembered the previously used effort for a model. The effort was held in a single transient state value: it reset to the model default on every mount and leaked across models, so selecting "high" for model A and "medium" for model B showed "medium" when switching back to A.

Effort is now persisted per model config ID in localStorage (agents.reasoning-effort.<id>), read on the New chat form, and restored when switching models. The persisted per-model value takes precedence over a root personal model override's reasoning_effort (the user's own most recent choice wins across sessions); the override still applies when nothing is persisted, and a stored value that is no longer valid for the model's current effort set is ignored so it cannot shadow the override. Storage failures (private mode, quota) degrade gracefully to in-memory-only memory.

Scope is deliberately limited to the New chat page. The existing-chat page's last_reasoning_effort behavior and the edit path are unchanged from main.

Refs CODAGT-799
Supersedes #27377

Note

🤖 This PR was written by Coder Agent on behalf of Danielle Maywood

@linear-code

linear-code Bot commented Jul 23, 2026

Copy link
Copy Markdown

CODAGT-799

@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

@coder-agents-review

coder-agents-review Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-07-23 11:14 UTC by @DanielleMaywood
Spend: $16.66 / $100.00

Review history
  • R1 (2026-07-23): 13 reviewers, 1 Nit, 3 Note, 2 P3, 1 P4, COMMENT. Review

deep-review v0.9.0 | Round 1 | f17d488..ca23321

Last posted: Round 1, 7 findings (2 P3, 1 P4, 1 Nit, 3 Note), COMMENT. Review

Finding inventory

Finding inventory - PR #27457

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 Note Open AgentCreateForm.tsx:264 Effort-precedence fix exercised only by Storybook play tests, not blocking CI (repo-wide infra gap) R1 Netero, confirmed by Pariston/Nami/Meruem Yes
CRF-2 P3 Open AgentCreateForm.tsx:256 Root override effort dropped after user selects any model (even its own); !hasValidUserSelectedModel gate reverts to model default, contradicting "override still applies" R1 Mafuuu Yes
CRF-3 P3 Open AgentCreateForm.tsx:378 Effort persists on every slider move (persist-on-change), so an unsubmitted preview durably shadows the account override next session; asymmetric with sibling persist-on-create R1 Pariston Yes
CRF-4 Nit Open AgentCreateForm.stories.tsx:460 SubmitsReasoningEffort lacks beforeEach: localStorage.clear(); safe only by harness isolation, diverges from file convention R1 Komugi Yes
CRF-5 P4 Open AgentCreateForm.stories.tsx:336 Graceful degrade-to-in-memory-only branch has no component test; only the unit no-throw path is covered R1 Bisky Yes
CRF-6 Note Open reasoningEffort.ts:21 Per-model localStorage keys never pruned on model-config deletion, unlike sibling keys in the same file R1 Hisoka, Pariston Yes
CRF-7 Note Open AgentCreateForm.tsx:266 Stale-value validation applied to only one of three ?? candidates; in-memory and override candidates enter raw (class not eliminated, low impact) R1 Meruem Yes

Round log

Round 1

Netero first pass (1 Note, CRF-1) then 13-reviewer panel (bisky, hisoka, mafu-san, mafuuu, pariston, ging-ts, ging-react, gon, leorio, nami, komugi, robin, + meruem wildcard). Panel: 2 P3, 1 P4, 1 Nit, 3 Notes. No P0-P2. Ging-ts, ging-react, gon, robin, mafu-san, nami returned no actionable findings. CRF-2 verified against code (handleModelChange unconditionally sets hasUserSelectedModel=true). Event: COMMENT. Reviewed against f17d488..ca23321.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a tight, well-tested fix. The per-model Record plus a localStorage layer cleanly separates the two symptoms (the cross-model leak vs the lack of cross-session memory), and it deliberately closes the stale-value shadowing trap (CRF-22) litigated on the superseded #27377 by validating the stored value against the model's current effort set before it enters the precedence chain. Test density is high (171 test / 65 production LOC) and the three new stories drive the real slider and the real submit payload rather than asserting mock echoes.

Severity count: 0 P0-P2, 2 P3, 1 P4, 1 Nit, 3 Notes.

The two P3s are worth a look before merge. CRF-2: the root-override effort is gated behind !hasValidUserSelectedModel, so selecting your override's own model in the dropdown drops the override effort back to the model default (verified: handleModelChange always sets the flag), which contradicts the PR's "the override still applies when nothing is persisted." CRF-3: effort persists on every slider move rather than on chat creation, so an unsubmitted preview durably outranks the account override next session, asymmetric with the sibling lastModelConfigID commit-on-create behavior. Both are bounded but deserve a deliberate call rather than silent acceptance.

Process note: the precedence and stale-value logic is covered only by Storybook play assertions, and the blocking CI job runs vitest run --project=unit only, so a regression in that chain produces no failing blocking-CI signal. This is a repo-wide infrastructure gap, not introduced here, and the author followed the project's story-based convention; flagged as CRF-1 so the coverage assumption is explicit.

Hisoka, on the diff: "I came looking for a fight. This one held its ground."

🤖 This review was automatically generated with Coder Agents.

Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.tsx Outdated
Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.tsx
Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.tsx
Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.tsx
Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.stories.tsx
Comment thread site/src/pages/AgentsPage/components/AgentCreateForm.stories.tsx
Comment thread site/src/pages/AgentsPage/utils/reasoningEffort.ts

@DanielleMaywood DanielleMaywood left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resolutions in 1ed7672:

  • CRF-2: fixed. Dropped the !hasValidUserSelectedModel term; selectedModel === rootOverrideModelID already scopes the override and it sits last in the chain, so a per-model or persisted pick still wins. New story ManualReselectKeepsRootOverrideEffort pins it.
  • CRF-3: deliberate keep of persist-on-change. It is what "remember the previously selected level" means to a user; persisting only at create would lose the choice when the create fails or the user navigates away. Description already says "selected", not "used".
  • CRF-4: the meta-level beforeEach: localStorage.clear() (line 125) already runs for every story including SubmitsReasoningEffort, providing the invariant. No story-level clear added; a redundant one on the new story was also removed.
  • CRF-5: declined. The unit test covers the no-throw contract; the in-memory path is simple and its failure mode benign. Not worth a story.
  • CRF-1/6/7: noted, no change (repo-wide CI gap; bounded unpruned keys the reviewer called not worth machinery; single-candidate stale validation the reviewer rated low impact).

@DanielleMaywood
DanielleMaywood marked this pull request as ready for review July 23, 2026 12:09
@DanielleMaywood
DanielleMaywood merged commit 9ce3664 into main Jul 23, 2026
31 checks passed
@DanielleMaywood
DanielleMaywood deleted the danielle/codagt-799-store-latest-selected-effort-level-for-each-model branch July 23, 2026 12:37
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants