perf(web): typing no longer re-renders the traits picker or attach button#23040

merged1
main
refactor/split2-composer-traits
opened4d agobyJJulius Marminge
View on GitHubTwo-way sync enabledPR last imported 4d ago

Typing in the composer re-rendered the traits picker and the attach button on every keystroke.

Traits picker. It took the whole prompt so it could tell whether Ultrathink was in it. It now takes promptUltrathink ("none" | "prefix" | "body"), which is all it reads while rendering. When a pick edits the prompt, the picker hands the composer an edit through onPromptEdit, and the composer applies it to the live draft. The settings pickers drop the prompt="" and no-op onPromptChange they used to pass.

Attach button. addComposerAttachments was declared before insertAttachmentReferences and insertComposerText, which it calls. The compiler does not memoize a function that refers to a later declaration, so the handler was rebuilt on every render. Those two helpers now come first, and insertAttachmentReferences calls the existing stable insert helpers instead of the cursor-bound ones. That also memoizes foldPastedText and the paste and drop handlers that capture it. No new useStableCallback.

Interaction (median of 3)mainthis PR
Type 20 chars: total renders344182
Type 20 chars: TraitsPicker / ComposerAttachButton20 / 200 / 0
Type 20 chars with an image attached: total302182
Open the slash menu: total450402
Traits Medium -> High: total288284
Filemainthis PR
ChatComposer.tsx6,3656,372

Tested:

  • vp test run src/components/chat/composerProviderState.test.tsx, which adds a readPromptUltrathink case.
  • React Compiler coverage for the touched files: 0 bailouts.
  • apps/web typecheck and lint on the changed files.
  • Hands-on with Claude Opus in a dev build. Picking Ultrathink adds the prefix. Picking High removes it. Typing "ultrathink" in the body disables the effort options and shows the notice. Pasting an image attaches it.

🤖 Generated with Claude Code

Checks

All checks passed

Added 1 commit

  • perf(web): typing no longer re-renders the traits picker or attach buttonec8a087
Synced from GitHub

Approvability

Verdict: Approved at ec8a087

Macroscope's review found this PR approvable — This is a bounded web performance refactor that replaces full prompt propagation with a stable Ultrathink summary and live prompt-edit callback, while retaining existing picker behavior. The settings changes remove obsolete no-op props and do not change product defaults or persisted selections.

You can add or adjust custom eligibility rules. Learn more.

Synced from GitHub

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Path: .coderabbit.config.ts
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 906d432e-e446-4b8f-82c2-d3d28b17b25e
📥 Commits

Reviewing files that changed from the base of the PR and between 0bdf33a34dc520d3ab1364cd116686b3492184bd and ec8a0878b4c9eb31ff47432a143893d0fedba6d9.

📒 Files selected for processing: 7
  • apps/web/src/components/chat/ChatComposer.tsx
  • apps/web/src/components/chat/TraitsPicker.tsx
  • apps/web/src/components/chat/composerProviderState.test.tsx
  • apps/web/src/components/chat/composerProviderState.tsx
  • apps/web/src/components/settings/ProjectDefaultsSettings.tsx
  • apps/web/src/components/settings/SettingsPanels.tsx
  • apps/web/src/components/settings/SourceControlWritingSettings.tsx
💤 Files with no reviewable changes: 3
  • apps/web/src/components/settings/ProjectDefaultsSettings.tsx
  • apps/web/src/components/settings/SettingsPanels.tsx
  • apps/web/src/components/settings/SourceControlWritingSettings.tsx

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.

📝 Walkthrough

The composer now routes trait prompt changes through transformations applied to the current draft. Trait controls use a classified Ultrathink state. Composer text and attachment-reference insertion helpers are relocated earlier in the component.

Changes: Prompt trait editing

Layer / File(s)Summary
Ultrathink classification and trait selection
apps/web/src/components/chat/TraitsPicker.tsx, apps/web/src/components/chat/composerProviderState.test.tsx
The picker classifies prompts as none, prefix, or body and uses that state for trait selection and visibility. Tests cover these classifications.
Draft prompt edit wiring
apps/web/src/components/chat/composerProviderState.tsx, apps/web/src/components/chat/ChatComposer.tsx, apps/web/src/components/settings/ProjectDefaultsSettings.tsx, apps/web/src/components/settings/SettingsPanels.tsx, apps/web/src/components/settings/SourceControlWritingSettings.tsx
Trait renderers receive classified prompt state and an edit callback. The composer applies transformations to the current draft and skips unchanged results. Settings picker calls remove unused prompt props and no-op callbacks.

Composer text and attachment insertion

Layer / File(s)Summary
Relocate composer insertion helpers
apps/web/src/components/chat/ChatComposer.tsx
Text and attachment-reference insertion helpers move earlier in the component. The helpers validate composer context and apply edits through stable insertion paths; their later duplicate definitions are removed.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Refactor

Suggested reviewers: maria-rcks

Merge Risk: ⚪ Minimal · up to ec8a0

No actionable regression was established in trait selection or composer insertion. The PR is mergeable after normal checks.

Pre-merge checks: Passed 3 · Failed 1

Failed Failed checks: 1 warning

Check nameStatusExplanationResolution
Description checkWarningThe description explains the problem, implementation, measurements, tests, and manual verification. It does not include the required Scope and approval section, and it omits the required before/after …Add the required Problem, Change, Scope and approval, and Verification headings. Document the triaged issue or maintainer approval, or explain why this focused fix is exempt. Add clear before/after UI screenshots and any required recording …
Passed Passed checks: 3 passed
Check nameStatusExplanation
Title checkPassedThe title clearly and concisely describes the main performance change: typing no longer re-renders the traits picker or attach button.
Linked Issues checkPassedCheck skipped because no linked issues were found for this pull request.
Out of Scope Changes checkPassedCheck skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description explains the problem, implementation, measurements, tests, and manual verification. It does not include the required Scope and approval section, and it omits the required before/after screenshots for a UI change.

Resolution

Add the required Problem, Change, Scope and approval, and Verification headings. Document the triaged issue or maintainer approval, or explain why this focused fix is exempt. Add clear before/after UI screenshots and any required recording for interaction timing.

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Synced from GitHub
⚠️ Action not completed

Already reviewed the last commit. Use @coderabbitai full review to rerun a review of the entire changeset.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.