MAINT Decompose ChatWindow conversation workflows
@PeaceMaker-best is already working on this.
Since Sep 14, 2026.
- Dominant language
- Python
- Stars
- 4.5k
- Forks
- 893
- Avg merge
- 3d 50m
- Merged PRs (30d)
- 165
Description
#### Is your feature request related to a problem? Please describe.
`frontend/src/components/Chat/ChatWindow.tsx` has become the owner of several independent workflows in one component. It currently coordinates message loading and stale-fetch protection, per-conversation send locks, optimistic messages, attachments and conversions, conversation creation/switching, copy and branch operations, human-score updates, objective changes, export, Markdown preferences, and responsive panel state.
The concern is not line count by itself. Race-sensitive state is spread across React state, multiple refs, effects, and callbacks, so changing one workflow requires understanding unrelated behavior. The associated tests also have to render a large surface to verify small state transitions.
#### Describe the solution you'd like
Decompose the stateful workflows behind focused hooks or reducers while keeping `ChatWindow` as the composition and presentation boundary. Candidate boundaries include:
- conversation message loading, navigation, and stale-response suppression;
- message sending, optimistic state, per-conversation locking, attachments, and conversions;
- copy/new-conversation/branch-conversation/branch-attack operations;
- human-score and objective mutations;
- export state and duplicate-export prevention.
Keep state together when it participates in the same transition. Prefer an explicit reducer for multi-step conversation mutation state over moving individual `useState` calls into pass-through hooks. The extracted APIs should return typed state and commands with clear ownership.
Preserve the existing `ChatWindow` props, rendered UX, accessibility, request payloads, optimistic-message behavior, navigation behavior, and error handling. In particular, retain the current protections against stale conversation loads, duplicate sends/exports, navigation during an in-flight send, and mutation while an operation is locked.
#### Describe alternatives you've considered, if relevant
Extracting only JSX sections into presentational components would shorten the file but leave the hard part, asynchronous state ownership, unchanged. Creating one large `useChatWindow` hook would move rather than reduce the complexity. The goal is a few cohesive workflow boundaries, not maximal file splitting.
#### Additional context
This was identified during the September 14, 2026 maintainability audit. A repository issue search found no exact existing tracker.
Suggested regression coverage:
- switching conversations while a fetch is in flight;
- sending independently in two conversations;
- preserving optimistic messages when the active conversation changes during send;
- duplicate-send and duplicate-export prevention;
- copy to current/new conversation and both branch paths;
- mutation locking during score, objective, and conversation updates;
- attachment and converted-piece handling;
- narrow-screen panel behavior.
Definition of done:
- each extracted hook/reducer owns one cohesive workflow and has focused tests;
- `ChatWindow` primarily composes workflow state and renders children;
- no public API, backend contract, accessibility, or user-visible behavior changes;
- frontend unit tests, type-check, lint, and formatting pass.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.