Thanks to visit codestin.com
Credit goes to github.com

Skip to content

fix(site/src/pages/AgentsPage): treat interrupting chats as busy in the composer - #28209

Merged
DanielleMaywood merged 9 commits into
mainfrom
danielle/chat-composer-interrupting
Aug 18, 2026
Merged

fix(site/src/pages/AgentsPage): treat interrupting chats as busy in the composer#28209
DanielleMaywood merged 9 commits into
mainfrom
danielle/chat-composer-interrupting

Conversation

@DanielleMaywood

@DanielleMaywood DanielleMaywood commented Aug 17, 2026

Copy link
Copy Markdown
Contributor

Fixes CODAGT-755

image

The chat composer derived isStreaming from hasStreamState || chatStatus === "running", excluding "interrupting". Once an interrupt is requested the stream state is already gone, so a chat still finalizing an interruption rendered the idle composer: no Stop button, the normal Send button, and no busy indication. The interrupting state was visually indistinguishable from waiting.

Include "interrupting" in the composer's streaming check and add Storybook coverage for the I1 state (interrupting with a queued message) alongside a running-state control.

Implementation notes (Coder Agents generated)
  • Verified against the backend state machine: waiting with a non-empty queue maps to StateInvalid (coderd/x/chatd/chatstate/state.go), so the observed "queued message with idle composer" symptom can only occur in the interrupting state (I1), where interrupt was requested and the stream has already been torn down.
  • The isActiveChatStatus helper in chatStore.ts already treats "interrupting" as active, but was only used for reconnect-state surfacing, not the composer.
  • Test approach: Storybook play assertions on ChatPageInput rendered with a real createChatStore(), asserting Stop is shown and Send is hidden while interrupting; the control story asserts the same rendering for running with an identical history and queue.
  • Frontend FE1-FE10 diff self-review: all rules pass.

…he composer

The composer derived isStreaming from hasStreamState or a running chat
status, excluding interrupting. Once an interrupt is requested the
stream state is gone, so a chat still finalizing an interruption
rendered the idle composer: no Stop button, the normal Send button,
and no busy indication. That made the interrupting state visually
indistinguishable from waiting.

Include interrupting in the composer's streaming check and add
Storybook coverage for the I1 state (interrupting with a queued
message) alongside a running-state control.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2969ae989f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatPageContent.tsx
Comment thread site/src/pages/AgentsPage/components/ChatPageContent.stories.tsx Outdated
…rupting

The interrupt POST resolves as soon as the request lands, but the
worker may finalize the interruption for several seconds, and the
backend rejects a second interrupt with 409. Gate the composer's stop
action on the interrupting status in addition to the mutation's
pending flag so neither the Stop button nor Escape re-fires an
interrupt that the close state machine (I0/I1) would reject.

Also trims the interrupting story comment to the non-obvious invariant
only.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ad127ef2f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatPageContent.stories.tsx Outdated
…story

The RunningShowsBusyComposer header comment restated what the story
code and assertions already say; FE4 prohibits that narration.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 3308c4f082

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatPageContent.tsx
Comment thread site/src/pages/AgentsPage/components/ChatPageContent.stories.tsx
Comment thread site/src/pages/AgentsPage/components/ChatPageContent.stories.tsx
…ueued-message fixture

The interrupting story now focuses the composer and sends Escape,
asserting the interrupt callback is not invoked while finalization is
still pending. The queued message is built from MockChatQueuedMessage
instead of an inline literal so fixture drift type-checks.

isActiveChatStatus is intentionally not reused for the composer's
busy check: it means active for store synchronization, a broader
contract than the composer needs, and conflating the two could show a
Stop button for a future busy status where interrupting is not legal.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cde235bdc7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatPageContent.stories.tsx Outdated
… role

Prefer getByRole("textbox", { name: "Chat message" }) over the test ID
when focusing the editor in the interrupting story, so a regression
that drops the accessible name fails instead of passing on a stale
test ID.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d6fbee2e6b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/ChatPageContent.tsx
…eyboard users

While an interrupt is finalizing, the composer's Stop button is
disabled and skipped in tab order, leaving keyboard and screen-reader
users with no indication that the interruption is still in progress.
Wrap the button in a tooltip that reads "Interrupting..." while
pending, and add an sr-only live region with role=status announcing
the same. The interrupting story now asserts the live region text.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 93eda335d3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread site/src/pages/AgentsPage/components/AgentChatInput.tsx
…during finalization

While an interrupt finalizes, the interrupted turn's flushed stream
state made the transcript render "Thinking" as if the agent were still
producing output. deriveLiveStatus now takes chatStatus and the new
interrupting phase outranks stream leftovers, so the activity slot
reads "Interrupting" with a pause icon (matching the sidebar's
interrupting status icon) instead. The interrupting story asserts the
transcript label and the absence of Thinking.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e72c31927f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +271 to +272
// The transcript must not claim the agent is still thinking while
// the interruption finalizes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove the new assertion-narrating comment

Fresh evidence after the earlier comment cleanups: this newly added comment merely restates the two assertions immediately below it, namely that the transcript shows Interrupting and does not show Thinking. Remove the narration and let the assertions describe the expected behavior, as required by FE4.

AGENTS.md reference: site/AGENTS.md:L15-L15

Useful? React with 👍 / 👎.

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.

Fixed in fcde0dd. Removed the comment; the assertions speak for themselves.

],
[
"interrupting",
{ chatStatus: "interrupting" as const },

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Type the case table instead of asserting the literal

The as const assertion is only compensating for widening in the heterogeneous it.each table and is avoidable by typing the case table or using satisfies. Remove the assertion so this test follows FE2's requirement to avoid unnecessary as casts rather than weakening inference at the value site.

AGENTS.md reference: site/AGENTS.md:L11-L12

Useful? React with 👍 / 👎.

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.

Fixed in fcde0dd. The it.each table is now a typed cases array (phase label, overrides, expected LiveStatusModel) and the expected-status fixtures use satisfies, so the interrupting row needs no cast at the value site.

….each typing

Removes a comment that restated the story assertions, and replaces the
as-const cast in the deriveLiveStatus case table with a typed cases
array plus satisfies annotations on the expected status fixtures.
@DanielleMaywood

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: fcde0ddeb2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@linear-code

linear-code Bot commented Aug 18, 2026

Copy link
Copy Markdown

CODAGT-755

@DanielleMaywood
DanielleMaywood marked this pull request as ready for review August 18, 2026 10:40
Comment thread site/src/pages/AgentsPage/components/ChatPageContent.tsx Outdated
@DanielleMaywood
DanielleMaywood merged commit 14e3ae3 into main Aug 18, 2026
26 checks passed
@DanielleMaywood
DanielleMaywood deleted the danielle/chat-composer-interrupting branch August 18, 2026 11:51
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 18, 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